home *** CD-ROM | disk | FTP | other *** search
/ Aminet 6 / Aminet 6 - June 1995.iso / Aminet / dev / e / EspanisTex.lha / E_spanish.tex (.txt)
Encoding:
LaTeX Document  |  1995-04-04  |  259.3 KB  |  5,369 lines

  1. %% Notas para la creaci
  2. n del fichero .dvi de impresi
  3. %% He intentado eliminar todas las dependencias con ficheros de formato
  4. %% de TeX que he podido para que se pueda pasar por plain TeX.
  5. %% Utiliza el comando 'itex E_spanish.tex'
  6. %% donde itex es 'virtex &iplain', y iplain se cre
  7.  utilizando:
  8. %%----inicio fichero
  9. %%\input plain
  10. %%\input amiga
  11. %%\def\fmtname{iplain}
  12. %%\dump
  13. %%----fin fichero
  14. amiga.tex lo puedes encontrar al final del fichero!!!
  15. %%  Las 
  16. nicas dependencias que quedan son las dos primeras l
  17. neas:
  18. %%\selectlanguage{spanish}
  19. %%  que es necesaria para que TeX incluya el guionado de forma correcta
  20. %%  esto forma parte del paquete 'babel'.  Puedes eliminar esta l
  21. %%  con lo que es probable que TeX utilice guionado ingles, y puede que
  22. %%  necesites indicar el punto de ruptura de algunas palabras con '\-'.
  23. %%\input manmac
  24. %%  manmac.tex deber
  25. a incluirse en tu distribuci
  26. n de TeX, si no,
  27. %%  contacta conmigo, y yo te puedo enviar una versi
  28. n de ese fichero.
  29. %%  u0868551@oboe.etsiig.uniovi.es
  30. % Este manual tiene copyright (C) 1995 de Antonio J. Gomez Gonzalez.
  31. % !`Reservados todos los derechos!
  32. \selectlanguage{spanish}
  33. \input manmac
  34. %% Mis macros para este libro
  35. \hsize=32pc    \vsize=52pc
  36. \hoffset=1.52cm %3.57pc
  37. \pagewidth=32pc \pageheight=52pc
  38. \parindent=2em
  39. \catcode`@=11 % borrow the private macros of PLAIN (with care)
  40. %% Si quieres obtener unas marcas para ver si las paginas quedan centradas,
  41. %% comenta la siguiente linea (con %).
  42. \def\setcornerrules{}
  43. \outer\def\subsec#1. {\medbreak\advance\subsecno by 1
  44.   \noindent{\it \the\subsecno.\enspace#1.\enspace}}
  45. \outer\def\adver'#1'#2'#3'{\d@nger {\bf #1}\hfil\break #3\hfil\break}
  46. \outer\def\error'#1'#2'#3'{\dd@nger {\bf #1}\hfil\break #3\hfil\break}
  47. \catcode`\@=\other
  48. \def\fadver{\endgraf\endgroup} % omits the \medbreak
  49. \def\ferror{\endgraf\endgroup} % omits the \medbreak
  50. \let\centrada=\centerline
  51. \let\derecha=\rightline
  52. \let\izquierda=\leftline
  53. \def\b/{/\penalty\exhyphenpenalty} % una `/' que actua como un `-'
  54. %% nueva macro para notas a pie de pagina numeradas de forma automatica.
  55. \newcount\numeronota
  56. \def\reinicianotas{\numeronota=0\relax}
  57. \def\nota{\advance\numeronota by 1
  58.   \footnote{$^{\the\numeronota}$}}
  59. %% fin nueva macro
  60. \outer\def\seccion#1. {\bigbreak
  61.   \subsecno=0
  62.   \noindent{\docess #1.\par\nobreak\smallskip\nobreak}\noindent}
  63. %% Yo prefiero los contenidos en tipo slanted
  64. \def\<#1>{\leavevmode\hbox{$\langle${\sl #1}\/$\rangle$}} % syntactic quantity
  65. \def\acerca{\stretch}
  66. \def\noin{\noindent}
  67. \def\bloque{\bull}
  68. \def\finpar{\parbreak}
  69. \def\lineas{\beginlines}
  70. \def\finlineas{\endlines}
  71. \def\finlineasligero{\weakendlines}
  72. \def\finlineasfinal{\finalendlines}
  73. \font\docess=cmss12
  74. \def\pregunta#1{\Espacio\item{$-$} {\sl #1}\par\nobreak\smallskip\nobreak}
  75. \def\ejemplos{\par\nobreak\vbox\bgroup\halign\bgroup ##\hfil&\qquad##\hfil\cr}
  76. \def\Ejemplos{\smallskip  \vbox\bgroup\halign\bgroup ##\hfil&\qquad##\hfil\cr}
  77. \def\fin{\egroup\egroup\noindent\ignorespaces}
  78. \def\finsma{\egroup\egroup\smallskip\noindent\ignorespaces}
  79. \def\finmed{\egroup\egroup\smallskip\noindent\ignorespaces}
  80. \def\proto#1{\medskip\noindent\quad{\tt #1}\par\nobreak\smallskip\nobreak\noindent\ignorespaces}
  81. \def\pproto#1{\vskip-\smallskipamount\noindent\quad{\tt #1}\par\nobreak\smallskip\nobreak\noindent\ignorespaces}
  82. \def\espacio{\smallskip\noindent\ignorespaces}
  83. \def\Espacio{\medskip\noindent\ignorespaces}
  84. \def\Esptab{\noalign{\medskip}}
  85. \def\esptab{\noalign{\smallskip}}
  86. \def\bartab{\noalign{\smallskip\hrule\smallskip}}
  87. \def\E/{Amiga~E}
  88. \def\ASCII/{{\sc ASCII}}
  89. \def\saltacap{\eject\reinicianotas}
  90. \titlepage
  91. \pageno=-1995
  92. \line{\cmman \hfill E\hfill}
  93. \vfill
  94. \line{\sl\hfill Por Antonio J. Gomez Gonzalez\hfill}
  95. \line{\sl\hfill u0868551@oboe.etsiig.uniovi.es\hfill}
  96. \eject
  97. % title
  98. \pageno=-1 % the front matter is numbered with roman numerals
  99. \font\auth=cmssdc10 scaled\magstep4 % used only on the title page
  100. \font\elevenbf=cmbx10 scaled\magstephalf % ditto
  101. \font\elevenit=cmti10 scaled\magstephalf % ditto
  102. \font\elevenrm=cmr10 scaled\magstephalf % ditto
  103. \titlepage
  104. \line{\cmman \hfill E\hfill}
  105. \vskip 1pc
  106. \baselineskip 13pt \elevenbf
  107. \halign to\hsize{#\hfil\tabskip 0pt plus 1fil&#\hfil\tabskip0pt\cr
  108. \kern5.5mm\auth Wouter \kern-1ptvan \kern-1ptOortmerssen&\cr
  109. \noalign{\vskip 12pc}
  110. &\elevenit Traducido por\cr
  111. &Antonio J. \kern-1ptGomez Glez\cr
  112. \noalign{\vfill}
  113. &Gij\'on\enspace$\cdot$\enspace Espa\~na\cr}
  114. \eject
  115. % copyright
  116. \titlepage
  117. \eightpoint
  118. \vbox to 8pc{}
  119. \noindent\strut
  120. Este manual describe la versi\'on 3.1a del compilador de \E/\null{}. Algunas
  121. de las caracter\'{\i}sticas avanzadas que se describen aqu\'{\i} no est\'an
  122. presentes en versiones anteriores.
  123. \Espacio
  124. Este texto est\'a dise\~nado para ser impreso, y difiere en ciertos aspectos
  125. de la gu\'{\i}a de |amigaguide| del compilador, aunque en muy pocos
  126. aspectos.
  127. \Espacio
  128. \E/ tiene copyright $\copyright$ de Wouter van Oortmerssen.
  129. \vfill
  130. \noindent
  131. {\sl \kern-1pt Segunda impresi\'on, revisada, Abril 1995} % hardcover
  132. \espacio
  133. Copyright $\copyright$ 1995 por Antonio Joqu\'{\i}n Gomez Gonzalez
  134. \espacio
  135. Este libro se publica como parte de la distribuci\'on de la versi\'on v3.1a
  136. de \E/\null{}.  Debe quedar claro que el \'unico responsable de la fiabilidad
  137. de esta traducci\'on es Antonio J.~Gomez Gonzalez, aunque por otra
  138. parte, no acepto ninguna responsabilidad sobre da\~nos provocados por su
  139. lectura, es decir, ac\'eptala como es.
  140. \Espacio
  141. ISBN 0-000-00000-0\par % paperback
  142. \eject
  143. \reinicianotas
  144. % the preface
  145. \titlepage
  146. \def\rhead{Introducci\'on}
  147. \vbox to 8pc{
  148. \derecha{\titlefont Introducci\'on}\vss}
  149. {\topskip 9pc % this makes equal sinkage throughout the Preface
  150. \vskip-\parskip
  151. \tenpoint
  152. \noindent\hang\hangafter-2
  153. \smash{\lower12pt\hbox to 0pt{\hskip-\hangindent\cmman G\hfill}}\hskip-4pt
  154. {\sc ENEROSO} L{\sc ECTOR}: \strut Este es un libro sobre \E/\null{}, el cual
  155. es un lenguaje de alto nivel orientado a objetos\b/procedural\b/funcional no  puro,
  156. influenciado en gran medida por lenguajes tales como C++,
  157. Ada,  Lisp, etc.  Es un lenguaje de programaci\'on de prop\'osito general, y
  158. la  implementaci\'on  para  Amiga est\'a dirigida espec\'{\i}ficamente a programar
  159. aplicaciones  de  sistema.   El n\'umero de caracter\'{\i}sticas del lenguaje es
  160. demasiado grande como para resumirlas todas, entre las cuales se incluye:
  161. velocidad  de  compilaci\'on superior a~20000 l\'{\i}neas por minuto en un Amiga
  162. a~7~Mhz,  ensamblador en l\'{\i}nea y enlazador\nota{linker.} integrados dentro del
  163. compilador,  un  gran  conjunto de funciones integradas, buen concepto de
  164. m\'odulos  con  includes  de  v39  como m\'odulos, sistema de tipos flexible,
  165. expresiones {\it entrecomilladas}, listas inmediatas, con tipo, polimorfismo
  166. a  bajo nivel y de objetos, manejo de excepciones, herencia, ocultamiento
  167. de  datos, m\'etodos, valores de retorno m\'ultiples, argumentos por omisi\'on,
  168. reserva de registros, manejo r\'apido de memoria, unificaci\'on, \hbox{Celdas-LISP},
  169. (macro-)preprocesador, depurador a nivel de fuente, y mucho m\'as~\dots
  170. \Espacio
  171. Veamos nuestro primer programa en E, el {\tt HolaMundo} de siempre:
  172. \begintt
  173. /* nominado para ejemplo `mas aburrido' */
  174. PROC main()
  175.   WriteF('!`Hola Mundo!\n')
  176. ENDPROC
  177. \endtt
  178. \noin La distribuci\'on incluye:
  179. \vbox{\settabs\+\indent&modules\qquad&\cr
  180. \+&bin/&     compilador |EC| y las utilidades de apoyo.\cr
  181. \+&modules/& m\'odulos E de Amiga v39 y utilidades en m\'odulos enlazables.\cr
  182. \+&docs/&    documentaci\'on de E.\cr
  183. \+&src/&     fuentes de ejemplo en E.\cr
  184. \+&tools/&   herramientas opcionales para usar con E.\cr
  185. \noin La distribuci\'on de \E/ v3.0 que incluye la versi\'on de demostraci\'on del
  186. compilador es FreeWare y se puede copiar libremente.  Algunos de vosotros habreis
  187. recibido un archivo con la versi\'on registrada del compilador, el cual {\bf NO} es
  188. FreeWare, y {\bf NADIE} m\'as debe copiarlo.
  189.    No est\'a autorizada la distribuci\'on de \E/ por un importe superior al de
  190. disco+correo (menos de 500~pts), as\'{\i} como tampoco se autoriza ning\'un otro tipo de
  191. distribuci\'on cuyo \'unico prop\'osito sea el de obtener beneficios.
  192.    {\bf Prohibo} a Serge Hamouche o su compa\~nia {\sl France Festival Distribution}
  193. distribuir E de forma alguna\nota{Serge Hamouche ha distribuido~E sin mi permiso,
  194. utilizando mi nombre de forma incorrecta y rob\'andome dinero a expensas de los
  195. programadores de~E franceses.  Si le has pagado dinero, recl\'amaselo y com\'enta esta
  196. situaci\'on a toda la gente que puedas para que no lo sigua haciendo.}.  Por otro
  197. lado, hay una traducci\'on de este documento en franc\'es con mi autorizaci\'on
  198. (realizada por Olivier~Anh) que est\'a disponible en Aminet.
  199.    Esta distribuci\'on debe ofrecerse siempre como un todo, es decir, de la misma
  200. forma que el archivo |.lha| original.  Sin a\~nadidos, modificaciones, traducciones,
  201. distribuciones parciales o cualquier otra cosa que se pueda hacer sin mi permiso.
  202. No hay garant\'{\i}as.  Si consigues ahogar al pez que tienes en la pecera usando~E, o
  203. si~E resulta no ser apropiado para pedir pizzas, ese es t\'u problema (y s\'olo tuyo).
  204. Pase lo que pase no me maldigas por ello.
  205. \medskip
  206.    Fred Fish tiene premiso especial para distribuir~E en sus \hbox{CD-ROMs}.
  207. \medskip
  208.    La distribuci\'on de \E/ es PD\null{}, y contiene la versi\'on demo del compilador.
  209. Los programadores registrados obtienen el compilador completo en un archivo a
  210. parte, en el que s\'olo est\'a |EC|.
  211.    As\'{\i} que, ?`que hay de la versi\'on demo que se incluye?  El compilador s\'olo crear\'a
  212. ejecutables de menos de 8KB, por encima de esos 8KB mostrar\'a el error
  213. |"workspace full"|\nota{espacio de trabajo lleno.} A parte de eso, es totalmente
  214. funcional.  Puedes evaluar la demo durante {\bf dos semanas}, tras las cuales debes
  215. decidir si registrarte o dejar de usarla, incluso si s\'olo escribes programas de
  216. menos de 8KB\nota{Sol\'{\i}an ser 12KB, s\'{\i}, !`adivina porqu\'e lo cambi\'e!}.
  217.    Para ver el coste de una copia, la forma de enviar el dinero, donde enviarlo,~\dots
  218. echa un vistazo a lo documentaci\'on electr\'onica de la distribuci\'on.  Aseg\'urate
  219. de enviar informaci\'on tan completa como puedas con el dinero, por ejemplo,
  220. direcci\'on completa, direcci\'on de correo electr\'onico, incluso puedes a\~nadir la
  221. configuraci\'on de tu Amiga.  Yo no voy a escribir aqu\'{\i} uno de esos tontos impresos
  222. de registro |:-)|
  223.    Las actualizaciones de la distribuci\'on se pueden encontrar en DP como siempre, y
  224. las actualizaciones del EC registrado se distribuyen como parches, tambi\'en en
  225. Dom\'{\i}nio P\'ublico.
  226.    Si ya has recibido el EC registrado, ser\'{\i}a conveniente que lo pusieras en el
  227. directorio |bin/|.  Todo el mundo puede copiar libremente el archivo de
  228. distribuci\'on, pero, por favor, aseg\'urate de que no distribuyes tu copia registrada
  229. de EC a nadie, ni siquiera a los amigos.  No he serializado esas copias por la
  230. confianza que tengo en mis usuarios registrados, por ello, no rompas esa confianza.
  231. La cuota de registro es bastante asequible, y la versi\'on v2.1b sigue estando
  232. disponible, por lo que no hay excusa para que piratees~E.
  233.    El compilador de \E/ ha sido desarrollado a lo largo de m\'as de tres~a\~nos
  234. y~medio, fruto de las ideas del autor sobre un buen lenguaje de programaci\'on, y un
  235. compilador de calidad espec\'{\i}fico del Amiga.  Ha sido programado (como podr\'as haber
  236. apreciado) 100\% en ensamblador, usando el ensamblador AsmOne~v1.02.  Todos los
  237. dem\'as programas de apoyo han sido programados en el propio \E/.
  238. \Espacio
  239. Agradezco especialmente a la siguiente gente:
  240. \vbox{\settabs\+\qquad&Jason Hualance\quad&\cr
  241. \+&Barry Wills&   $-$ por ser el mejor mejor betatester de siempre.\cr
  242. \+&Jason Hulance& $-$ por su trabajo en {\sl The Beginners Guide}, y betatest.\cr
  243. \+&Rob Verver&    $-$ por comentarios/inspiraci\'on.\cr
  244. \noin Tambi\'en me gustar\'{\i}a agredecer a los siguientes por varias razones (sin un
  245. orden particular) :
  246. \midinsert\narrower
  247. \noin Raymond Hoving,  Erwin van~Breemen, Michael  Zuchhi, James  Cooper, Jens
  248. Gelhar,  Paolo Silvera,  Sergio  Ruocco, Jeroen Vermeulen,  Jan van den
  249. Baard, Joerg Wach, Norman Kraft, Urban Mueller, Charles McCreary, Olivier
  250. Anh, Lionel Vintenat, Rob Nottage, and many more~\dots
  251. \endinsert
  252.    Este compilador se ha programado poniendo mucho cuidado en lo referente a
  253. fiabilidad, y m\'as cuidado a\'un en el c\'odigo que genera, adem\'as ha sido comprobado y
  254. depurado durante largo tiempo.  Sin embargo, es muy posible que contenga alg\'un
  255. error.  Si llegas a encontrar uno, o tienes otros comentarios\b/preguntas,
  256. escr\'{\i}beme a la direcci\'on de m\'as abajo:  Prefiero {\bf con diferencia} correo
  257. electr\'onico sobre correo convencional.
  258. {\bf Apunta bien}:  debido a la gran popularidad de las versiones anteriores de
  259. \E/, recibo una cantidad casi incontestable de correo electr\'onico, buena parte
  260. del cual (|>90%|) son preguntas que no ser\'{\i}an necesarias si la gente leyera los
  261. documentos con cuidado.  Lo que quiero decir es que me gusta recibir correo
  262. electr\'onico, y no me importa responder preguntas y ayudar a la gente con problemas
  263. de programaci\'on, pero, antes de escribirme, aseg\'urate de comprobar los documentos
  264. que tienes a tu disposici\'on (como los documentos de \E/ o los RKRMs) para ver si la
  265. pregunta es relevante.  M\'as precismente, no debeis enviarme preguntas que no son
  266. espec\'{\i}ficas de E, sino del Amiga.  E~intenta ser amable conmigo con comentarios
  267. como ``{\sl Yo creo que \E/ debe tener la caracter\'{\i}stica X\/}~\dots ''\nota{N.T.:
  268. por supuesto en ingl\'es $;-)$}.  Hecha un vistazo a la FAQ.
  269. \Espacio
  270. Ser\'an bien recibidos registros y donaciones en la siguiente direcci\'on:
  271. \vbox{\settabs\+\indent\qquad&\cr
  272. \+&Wouter van Oortmerssen\cr
  273. \+&Levendaal 87\cr
  274. \+&2311 JG  Leiden\cr
  275. \+&HOLANDA\cr
  276. \noin o, mejor, si tienes acceso a correo electr\'onico:
  277. \vbox{\settabs\+\indent\qquad&\cr
  278. \+&wouter@mars.let.uva.nl\cr
  279. \+&wouter@alf.let.uva.nl\qquad (si mars rebota)\cr
  280. \bigskip
  281. \line{{\sl Gij\'on, Asturias}\hfil--- A. J. G. G.}
  282. \line{\sl Marzo 1995\hfil}
  283. } % end of the special \topskip
  284. \endchapter\saltacap
  285. \beginchapter Cap\'{\i}tulo 1. Usando el\\compilador
  286. \pageno=1 % Pagina numero 1
  287. Para instalar \E/ en tu sistema, s\'olo tienes que copiar toda la distribuci\'on en
  288. alg\'un lugar de tu sistema, extender tu path al directorio |BIN|, \thinspace y
  289. asignar |EModules:| \negthinspace al directorio |MODULES|.
  290. \espacio
  291. Sintaxis del compilador (2.04+):
  292. \begintt
  293. SOURCE/A,REG=NUMREGALLOC/N/K,LARGE/S,SYM=SYMBOLHUNK/S,NOWARN/S,
  294. QUIET/S,ASM/S,ERRLINE/S,ERRBYTE/S,SHOWBUF/S,ADDBUF/N/K,
  295. IGNORECACHE/S,HOLD/S,WB/S,LINEDEBUG/S,OPTI/S,DEBUG/S:
  296. \endtt
  297. Sintaxis para 1.2 a 2.03:
  298. \begintt
  299. EC [-opcs] <fichero_fuente>
  300. \endtt
  301.    Puedes  ver  las opciones estandard de AmigaDos en cualquier momento
  302. escribiendo  `|EC ?|'.  Las opciones en las versiones \hbox{1.2$-$2.03} del sistema
  303. son  de  tipo Unix (hay que escribirlas todas juntas, precedidas de ``$-$''). La mayor
  304. parte de las veces no necesitar\'as usar estas opciones.  Veamos su significado:
  305. \smallskip
  306. \vbox{\halign{{\tt#}\hfil&\enspace{\tt#}\hfil&
  307.          \enspace\vtop{\parindent=0pt\hsize=24pc\hangindent=0pt\strut#\strut}\cr
  308. 2.04+&1.2+&Descripci\'on\cr
  309. \bartab
  310. LARGE&       -l&  Compila con modelo c\'odigo/datos grande. \hfill|OPT LARGE|\cr
  311. ASM&         -a&  Pasa |EC| a modo ensamblador.\hfill|OPT ASM|\cr
  312. NOWARN&      -n&  Suprime advertencias.\hfill|OPT NOWARN|\cr
  313. SYM&         -s&  Inserta un |symbolhunk| al ejecutable,  que utilizar\'an
  314.                   los profilers, depuradores, desensambladores~\dots\cr
  315. LINEDEBUG&   -L&  Inserta bloque de depuraci\'on  |LINE|  al ejecutable,
  316.                   para profilers, depuradores,~\dots \hfill|OPT LINEDEBUG|\cr
  317. REG=N&       -rN& Hace que se reserven  |N|  registros por |PROC|\null{}.  (0~por
  318.                   omisi\'on, !`mira en alg\'un otro sitio sobre esto!)\cr
  319. QUIET&       -q&  Pone |EC| en modo silencioso,  s\'olo escribe cuando hay\
  320.                   errores o advertencias.\cr
  321. WB&          -w&  Pone el WB delante (para scripts).\cr
  322. SHOWBUF&     -b&  Muestra informaci\'on de uso de memoria de buffer.\cr
  323. ADDBUF=X&    -mX& Hace que |EC| reserve m\'as memoria para buffers. |X| est\'a
  324.                   en el intervalo  1--9  ---n\'umero de m\'{\i}nimo de bloques
  325.                   de 100KB reservados. (1~por omisi\'on, casi no se usa)\cr
  326. ERRLINE&     -e&  |EC| retorna el n\'umero de l\'{\i}nea del error.\cr
  327. ERRBYTE&     -E&  |EC| retorna la posici\'on (en bytes) respecto al inicio
  328.                   del fichero en la que se produjo el error.\cr
  329. IGNORECACHE& -c&  Deshabilita el uso del cach\'e de m\'odulos.\cr
  330. HOLD&        -h&  Espera a que se pulse \<|return|> antes de continuar.\cr
  331. OPTI&          &  Activa las optimizaciones (de momento es |REG=5|).\cr
  332. DEBUG&         &  Inserta informaci\'on de depuraci\'on en ejecutable o m\'odulo.\cr
  333. \espacio
  334. Por ejemplo, |ec LARGE blabla| compila |blabla.e| con modelo grande.
  335. \medskip
  336.    El compilador no se puede hacer residente.  Si un programa usa ficheros
  337. m\'odulo para definiciones de biblioteca como:
  338. \ejemplos
  339. &|MODULE 'GadTools', 'Reqtools'|\cr
  340. el compilador necesita saber donde est\'an.  Hay dos posibles soluciones:\par
  341. 1. Realizar la asignaci\'on \hbox{|EModules:|} al directorio de m\'odulos (mejor).\par
  342. 2. Indicar en el c\'odigo fuente donde debe buscar los m\'odulos, como:
  343. \ejemplos
  344. &|OPT DIR='dh0:src/e/modules'|\cr
  345. \medskip
  346.    Veamos como ejemplo la compilaci\'on del programa |HolaMundo.e|.  El compilador producir\'a
  347. un ejecutable |HolaMundo|.
  348. \begintt
  349. E:>  ec holamundo
  350. Amiga
  351. Compiler/Assembler/Linker
  352. v2.4f
  353. 91/92/93
  354. lexical analysing ...
  355. parsing and compiling ...
  356. no errors
  357. E:>  holamundo
  358. !`Hola Mundo!
  359. E:>  list
  360. HolaMundo.e                   89 ----rwed Hoy       17:37:00
  361. HolaMundo                    656 ----rwed Hoy       17:37:00
  362. 2 files - 4 blocks used
  363. \endtt
  364. \endchapter\saltacap
  365. \beginchapter Cap\'{\i}tulo 2. Formato del\\lenguaje
  366. \subsec Tabuladores, cambio de l\'{\i}nea, etc.
  367. El c\'odigo fuente en~E son ficheros en formato \ASCII/ puro, con cambio de l\'{\i}nea
  368. \<|lf|> y punto y coma |;| como separadores de dos sentencias.  Las sentencias que
  369. tengan un n\'umero particularmente grande de elementos se pueden repartir a lo largo
  370. de varias l\'{\i}neas finaliz\'andolas con una coma (o con cualquier otro elemento l\'exico
  371. que normalmente no puede aparecer en el fin de l\'{\i}nea), ignorando de esa forma el
  372. siguiente \<|lf|>.
  373. \noin En un fichero de c\'odigo fuente los elementos l\'exicos pueden estar separados
  374. entre s\'{\i} por cualquier n\'umero de espacios, tabuladores,~\dots
  375. \subsec Comentarios.
  376. En un fichero fuente los comentarios se pueden poner en cualquier lugar en
  377. el que normalmente un espacio ser\'{\i}a correcto.  Empiezan con |/*| y finalizan
  378. con |*/|, y se pueden anidar infinitamente.  Lo mismo se puede decir para
  379. los comentarios de una l\'{\i}nea, los cuales empiezan con un |->| y finalizan en
  380. el primer \<|lf|>.
  381. \begintt
  382. /* esto es un comentario */
  383. -> esto tambi\'en.
  384. \endtt
  385. \subsec Identificadores y tipos.
  386. Los identificadores son cadenas que el programador usa para denotar un
  387. cierto objeto, en la mayor\'{\i}a de los casos variables, o incluso palabras
  388. claves o nombres de funciones predefinidas por el compilador.  Un
  389. identificador est\'a formado por:
  390. {\obeylines
  391. $-$ caracteres en may\'uscula o min\'uscula.
  392. $-$ |0...9| (excepto como primer caracter).
  393. $-$ |_| (el subrayado).
  394. \espacio
  395. Todos los caracteres son significativos, aunque el compilador s\'olo
  396. mira los dos primeros para determinar el tipo de identificador con el que
  397. est\'a tratando:
  398. \Ejemplos
  399. \qquad Ambos en may\'uscula:&palabra clave como |IF|, |PROC|,~\dots\cr
  400.                           &constante, como |MAX_LENGTH|,~\dots\cr
  401.                           &mnemot\'ecinico ensamblador, como |MOVE|,~\dots\cr
  402. \qquad Primera min\'uscula  &identificador de variable/etiqueta/objeto,~\dots\cr
  403. \qquad Primera may\'us.\ y seg.\ min\'us.&funci\'on del sistema E como: |WriteF()|,~\dots\cr
  404.                                      &llamada de librer\'{\i}a: |OpenWindow()|,~\dots\cr
  405. Todos los identificadores verifican esta sintaxis, por
  406. ejemplo:  |WBenchToFront()| se convierte en |WbenchToFront()|.
  407. \Espacio
  408. A nivel sem\'antico, los programas en~E estan formados por expresiones.  Una
  409. expresi\'on es un fragmento de c\'odigo formado por operadores, funciones y
  410. par\'entesis que conforman un valor.  La mayor\'{\i}a est\'an formadas por:
  411. {\obeylines
  412. $-$ valores inmediatos.
  413. $-$ operadores (Matem\'aticos,~\dots)
  414. $-$ llamadas a funciones.
  415. $-$ par\'entesis |()| ---determinando precedencia y agrupamiento.
  416. $-$ variables o expresiones variables.
  417. \Ejemplos
  418. Ejemplos de expresiones:&|1                      'hola'|\cr
  419.                         &|$ABCD+(2*6)+Abs(a)   (a<1) OR (b>=100)|\cr
  420. \finsma
  421. Veamos algunos de estos elementos:
  422. \subsec Precedencia y agrupamiento.
  423. El lenguaje E no tiene ning\'un tipo de precedencia.  Esto quiere decir que
  424. las expresiones se eval\'uan de izquierda a derecha.  Puedes cambiar la
  425. precedencia encerrando entre par\'entesis algunas (sub-)expresiones.
  426. \Ejemplos
  427. Ejemplos:&|1+2*3 /* =9 */   1+(2*3) /* =7 */   2*3+1  /* =7 */|\cr
  428. \subsec Expresiones.
  429. Hay tres tipos de expresiones, y se pueden usar con diferentes prop\'ositos:
  430. \item{$-$} \<var>, formada simplemente por una variable.
  431. \item{$-$} \<expvar>, formada por una variable, posiblemente con operadores
  432.            unarios como ``|++|'' (incremento), ``|.|'' (selecci\'on de
  433.            miembro) o ``|[]|'' (operador de arreglo).  Denota una expresi\'on
  434.            modificable (como los valores-i\nota{l-values.} del~C).  Se\~nalar
  435.            que esos operadores (unarios) no forman parte de ninguna
  436.            precedencia.
  437. \item{$-$} \<exp>. Incluye \<var> y \<expvar>, y cualquier otra expresi\'on.
  438. \subsec Llamadas a funciones.
  439. La llamada a una funci\'on es una suspensi\'on temporal del c\'odigo actual
  440. para {\it saltar} a esa funci\'on, \'esta puede ser una funci\'on escrita por uno
  441. mismo (|PROC|), o una funci\'on proporcionada por el sistema.  El formato de
  442. una llamada a funci\'on es, el nombre de la funci\'on seguido de dos par\'entesis
  443. que encierran argumentos que pueden ser desde~0 hasta un n\'umero ilimitado de
  444. ellos, que van separados por comas ``|,|''.  Se\~nalar que los argumentos de
  445. funciones son expresiones de nuevo.
  446. \Ejemplos
  447. Ejemplos:&|foo( 1, 2 )|\cr
  448.          &|Gadget( buffer, glist, 2, 0, 40, 80+offset, 100, 'Cancela' )|\cr
  449.          &|Close( handle )|\cr
  450. \finsma
  451. Tanto los valores inmediatos como los operadores se detallan en los
  452. pr\'oximos cap\'{\i}tulos.
  453. \endchapter\saltacap
  454. \beginchapter Cap\'{\i}tulo 3. Valores\\inmediatos
  455. Todos los valores inmediatos en~E se eval\'uan a un resultado de 32~bits, la
  456. \'unica diferencia entre todos ellos puede ser su representaci\'on interna, o el
  457. hecho de que retornen un puntero en vez de un valor.
  458. \subsec Decimal (|1|\/).
  459. Un valor decimal es una sequencia de caracteres |0...9|, posiblemente
  460. precedidos de un signo menos ``|-|'' (denotando un valor negativo).
  461. \Ejemplos
  462. Ejemplos:&|1, 100, -12, 1024|\cr
  463. \subsec Hexadecimal (|\$1|\/).
  464. Un valor hexadecimal usa adem\'as los caracteres |A...F| (o |a...f|) y
  465. van precedidos por el caracter |$|.
  466. \Ejemplos
  467. Ejemplos:&|$FC, $DFF180, -$ABCD|\cr
  468. \subsec Binario (|\%1|\/).
  469. Los n\'umeros binarios empiezan con un caracter |%| y s\'olo usan los caracteres
  470. |1| y |0| para formar un valor.
  471. \Ejemplos
  472. Ejemplos:&|%111, %1010100001, -%10101|\cr
  473. \subsec Real (|1.0|\/).
  474. Los n\'umeros reales difieren de los decimales en que tienen un ``|.|'' para
  475. separar sus dos partes.  Se puede prescindir de cualquiera de las partes,
  476. pero nunca las dos.  Se\~nalar que la representaci\'on interna de los n\'umeros
  477. reales es diferente (32 bits {\sc IEEE}).
  478. \Ejemplos
  479. Ejemplos:&|3.14159, .1 (=0.1), 1. (=1.0)|\cr
  480. \subsec Caracter (|"a"|\/).
  481. El valor de un caracter (entre comillas |""|) es su valor \ASCII/, con esto
  482. tenemos que |"A" = 65|.  En~E los valores caracter inmediatos forman una
  483. peque\~na cadena de hasta cuatro caracteres, por ejemplo |"FORM"|, en la que
  484. el primer caracter (|"F"|) es el MSB (Byte M\'as Significativo) de la
  485. representaci\'on de 32~bits, y |"M"| es el LSB (Byte menos Significativo).
  486. \subsec Cadena (|'bla'|\/).
  487. Una cadena es la represtaci\'on \ASCII/ de una secuencia de caracteres que se
  488. escribe entre comillas simples |''|.  El valor de tales tipos de cadena es
  489. un puntero al primer caracter de la misma.  M\'as espec\'{\i}ficamente:  |'bla'|
  490. representa un puntero de 32~bits a un \'area de memoria en la que
  491. encontraremos los bytes |"b"|, |"l"| y |"a"|.  En~E todas las cadenas
  492. terminan con un byte cero.
  493. \noin Las cadenas pueden contener signos de formato introducidos con una
  494. barra inversa |\|, ya sea para introducir en la cadena caracteres que no
  495. son, por alguna raz\'on, visualizables, o para usarla con funciones de
  496. formateo de cadenas como |WriteF()|, |TextF()| y |StringF()|, o la funci\'on
  497. |Vprintf()| de KickStart~2.
  498. \Ejemplos
  499. \qquad |\n|&        cambio de l\'{\i}nea (\ASCII/ 10)\cr
  500. \qquad |\a| o |''|& ap\'ostrofe: |'| (el usado para encerrar la cadena)\cr
  501. \qquad |\q|&        dobles comillas: |"|\cr
  502. \qquad |\e|&        escape (\ASCII/ 27)\cr
  503. \qquad |\t|&        tabulador (\ASCII/ 9)\cr
  504. \qquad |\\|&        la propia barra inversa\cr
  505. \qquad |\0|&        byte cero. De escaso uso (todas las cadenas acaban en 0)\cr
  506. \qquad |\b|&        retorno de carro (\ASCII/ 13)\cr
  507. \finsma
  508. Adem\'as, cuando se usan con funciones de formateo:
  509. \Ejemplos
  510. \qquad |\d|& escribe un n\'umero decimal\cr
  511. \qquad |\h|& escribe un n\'umero hexadecimal\cr
  512. \qquad |\s|& escribe una cadena\cr
  513. \qquad |\c|& escribe un caracter\cr
  514. \qquad |\z|& fija el byte de relleno al caracter |0|\cr
  515. \qquad |\l|& ajusta a el campo a la izquierda\cr
  516. \qquad |\r|& ajusta a el campo a la derecha (ambos act\'uan como interruptores)\cr
  517. \finsma
  518. A los c\'odigos |\d|, |\h| y |\s| les pueden seguir especificadores de campo:
  519. \Ejemplos
  520. \qquad |[x]|&   indica el ancho exacto del campo, |x|\cr
  521. \qquad |(x,y)|& indica el ancho m\'{\i}nimo (|x|) y m\'aximo (|y|), s\'olo con cadenas\cr
  522. \Ejemplos
  523. Ejemplo:&escribir un n\'umero hexadecimal con 8 posiciones y ceros delante:\cr
  524.         &|WriteF('\z\h[8]\n',num)|\cr
  525. \finsma
  526. Una cadena se puede extender sobre varias l\'{\i}neas continu\'andolas con un
  527. signo |+| y un \<|lf|>:
  528. \begintt
  529. 'esta es una cadena deliberadamente larga que ' +
  530. 'esta dividida en dos lineas separadas'
  531. \endtt
  532. \subsec Lista (|[1,2,3]|\/) y lista con tipos.
  533. Una lista inmediata es la forma constante del tipo de datos |LIST|a, de
  534. la misma  forma que una  |'cadena'| es la forma  constante de los  tipos de
  535. datos |STRING| ({\it cadena}\/) o |ARRAY OF CHAR| ({\it arreglo de caracteres}\/).
  536. \Ejemplos
  537. Ejemplo:&|[3,2,1,4]|\cr
  538. \finsma
  539. Es una expresi\'on que tiene como valor un puntero a una lista ya
  540. inicializada.  La representaci\'on en memoria de una lista es compatible
  541. con un |ARRAY OF LONG|, con informaci\'on extra sobre la longitud en un
  542. offset negativo.  Puedes usar estas listas inmediatas en cualquier lugar
  543. en el que una funci\'on espere un |PTR| a un arreglo de valores de 32~bits,
  544. o una lista.
  545. \Ejemplos
  546. Ejemplos:&|['string',1.0,2.1]|\cr
  547.          &|[WA_FLAGS,1,WA_IDCMP,$200,WA_WIDTH,120,WA_HEIGHT,150,TAG_DONE]|\cr
  548. \subsec Celdas-lisp (|<a|\||b>|\/).
  549. Sobre \'estas es mejor que mires en el apartado sobre {\sl Celdas-Lisp y
  550. funciones de celdas}.
  551. \endchapter\saltacap
  552. \beginchapter Cap\'{\i}tulo 4. Operadores
  553. \subsec Matem\'aticos (|+ - * /|\/).
  554. Estos operadores infijos combinan una expresi\'on con otro valor para
  555. obtener un nuevo valor.  ``|-|'' se puede usar como primera parte de una
  556. expresi\'on, lo cual implica un~0\nota{es decir, |-exp| equivale a |0-exp|.}.
  557. Tambien hay que se\~nalar que por omisi\'on |*| y |/| son operadores de 16~bits.
  558. \Ejemplos
  559. Ejemplos:&|1+2, MAX-1*5, -a , -b+1|\cr
  560. \finsma
  561. Es interesante conocer los procedimientos |Mul()| y |Div()|, que
  562. realizan aritm\'etica de 32~bits, as\'{\i} como la sobrecarga de operadores para poder
  563. utilizarlos con n\'umeros reales.  Todo esto se detallar\'a en pr\'oximos cap\'{\i}tulos.
  564. \subsec Comparaci\'on (|= <> > < >= <=|\/).
  565. Igual que los operadores matem\'aticos, con la diferencia de que los
  566. resultados son, o |TRUE| (cierto, valor de 32~bits |-1|), o |FALSE| (falso).
  567. Tambi\'en se pueden sobrecargar para operar con reales.
  568. \subsec L\'ogica y con bits (|AND OR|\/).
  569. Estos operadores pueden combinar valores de verdad para obtener unos
  570. nuevos, o realizar operaciones |AND| y |OR| con bits.
  571. \Ejemplos
  572. Ejemplos:&|(a>1) AND ((b=2) OR (c>=3))   /* logica   */|\cr
  573.          &|a:=b AND $FF                  /* con bits */|\cr
  574. \subsec (|SIZEOF \^{} -- ++ ` |$\tt \{\}$).
  575. \item{$-$} |SIZEOF |\<identobjeto>
  576. \item{} Simplemente retorna el tama\~no de cierto objeto o |CHAR/INT/LONG|.
  577. \espacio
  578. \item{} Ejemplo:\quad |SIZEOF newscreen + SIZEOF INT|
  579. \espacio
  580. \item{$-$} $\{$\<var>$\}$
  581. \item{} Retorna la direcci\'on de una variable o etiqueta.  Este es el operador
  582.         que usar\'{\i}as para pasar una variable como argumento de una fucni\'on por
  583.         referencia, en lugar de por valor, que es la forma por omisi\'on en E.
  584. \item{} Ejemplo:\quad |Val(input,{x})|
  585. \espacio
  586. \item{$-$} |^|\<var>
  587. \item{} El compa\~nero de |{}|, escribe o lee variables que se han pasado por
  588.         referencia.  Tambi\'en se puede usar para {\it leer {\rm o} escribir}
  589.         de forma directa valores |LONG| de memoria, si \<var> es un puntero
  590.         a tal valor.
  591. \ejemplos
  592. \qquad Ejemplos:&|^a:=1  b:=^a|\cr
  593.                 &|PROC set(var,exp)  -> Funcion propia de asignacion...|\cr
  594.                 &|   ^var:=exp       -> Para ser llamada con set({a},1),|\cr
  595.                 &|ENDPROC            -> de forma que equivale a :  `a:=1'|\cr
  596. \finsma
  597. \item{$-$} \<varexp>|++|   y  \<varexp>|--|
  598. \item{} Incrementa (|++|) o decrementa (|--|) el puntero que se denota con
  599.         \<varexp> en el tama\~no de los datos a los que apunta.  Esto tiene el
  600.         efecto de que ese puntero apuntar\'a al elemento siguiente o anterior.
  601.         Cuando se usa con variables que no son punteros, esas se modificar\'an
  602.         simplemente en uno.  Se\~nalar que |++| siempre act\'ua despu\'es del
  603.         c\'alculo de \<varexp>, |--|, sin embargo, act\'ua {\it antes}.
  604. \ejemplos
  605. \qquad Ejemplos:&|a++   |, devuelve el valor de |a|, y luego incrementa |a|.\cr
  606.                 &|sp[]--|, decrementa puntero |sp| en 4  (|ARRAYs OF LONG|),\cr
  607.                 &|      |, y luego lee el valor al que apunta |sp|.\cr
  608. \finsma
  609. \item{$-$} |`|\<exp>
  610. \item{} Se le llama expresi\'on entrecomillada, del {\sc LISP}.  \<exp> no se
  611.         eval\'ua, pero en su lugar devuelve la direcci\'on de la expresi\'on, que
  612.         se puede evaluar m\'as tarde cuando se necesite.
  613. \subsec Triplete (|IF THEN ELSE|\/).
  614. El operador |IF| tiene una funci\'on similar a la sentencia |IF|, la \'unica
  615. diferencia es que selecciona entre dos expresiones en vez de entre dos
  616. sentencias o bloques de sentencias.  Igual que el operador |x?y:z| del~C.
  617. \Ejemplos
  618. &|IF| \<expbool> |THEN| \<exp1> |ELSE| \<exp2>\cr
  619. retorna \<exp> o \<exp2>, dependiendo de \<expbool>.
  620. \noin Por ejemplo, en vez de:
  621. \ejemplos
  622. &|IF a<1 THEN b:=2 ELSE b:=3|\cr
  623. &|IF x=3 THEN WriteF('x es 3\n') ELSE WriteF('x es otra cosa\n')|\cr
  624. puedes escribir:
  625. \ejemplos
  626. &|b:=IF a<1 THEN 2 ELSE 3|\cr
  627. &|WriteF(IF x=3 THEN 'x es 3\n' ELSE 'x es otra cosa\n')|\cr
  628. \subsec Estructura ({|.|}).
  629. \<ptrAobjeto>|.|\<miembrodeobjeto> construye una \<expvar>.  El puntero debe
  630. declararse |PTR TO| \<objeto> o |ARRAY OF| \<objeto> y el miembro debe ser
  631. un identificador legal de objeto.  Fij\'ate que el leer un subobjeto de un
  632. objeto de esta forma resulta en un puntero a ese objeto.
  633. \Ejemplos
  634. Ejemplos:&|estatarea.userdata:=1  rast:=mipantalla.rastport|\cr
  635. \finsma
  636. Si el miembro que selecciona es de tipo |PTR TO| \<tipo>, puedes usar
  637. ``|.|'' y |[]| para referirte a nuevos valores.  Si seleccionas un |ARRAY| o
  638. una subestructura en un |OBJECT|, el resultado es de nuevo un |PTR|.
  639. \subsec Arreglos (|[]|).
  640. \<var>|[|\<exp\'{\i}ndice>|]| (es una \<expvar>).  Este operador lee el valor del
  641. arreglo al que apunta \<var>, de \'{\i}ndice\nota{en un arreglo de $n$ elementos,
  642. el \'{\i}ndice var\'{\i}a entre $0\ldots n\!-\!1$} \<exp\'{\i}ndice>.  El \'{\i}ndice puede ser
  643. pr\'acticamente cualquier expresi\'on.  Debemos saber que |[]| es una
  644. abreviatura de |[0]|.
  645. \Ejemplos
  646. Ejemplos:&|a[1]:=10       |, pone el segundo elemento a 10.\cr
  647.          &|x:=table[y*4+1]|, lee del arreglo.\cr
  648.          &|x.y[3]         |, accede al arreglo dentro de un objeto.\cr
  649. \subsec Operador real (|!|\/).
  650. \<exp>|!|\<exp>.  Convierte una espresi\'on de entero a real y viceversa, y
  651. sobrecarga los operadores |+ - * / = <> < > <= >=| con equivalentes para
  652. reales.
  653. \subsec Expresiones de asignaci\'on (|:=|\/).
  654. La asignaci\'on (dar un valor a una variable) existe como sentencia y como
  655. expresi\'on.  La \'unica diferencia es que la versi\'on como sentencia tiene la
  656. forma \<expvar>|:=|\<exp> y la expresi\'on \<var>|:=|\<exp>.  Esta \'ultima
  657. tiene el valor de \<exp> como resultado.
  658. \noin F\'{\i}jate en que como \<var>|:=| tiene lugar en una expresi\'on, a menudo
  659. tendr\'as que ponerla entre par\'entesis para forzar su correcta interpretaci\'on,
  660. como:
  661. \ejemplos
  662. &|IF mem:=New(100)=NIL THEN error()|\cr
  663. se interpreta como:
  664. \ejemplos
  665. &|IF mem:=(New(100)=NIL) THEN error()|\cr
  666. y que no es lo que quieres: |mem| debe ser un puntero, no un booleano.
  667. Lo que se debe escribir es:
  668. \ejemplos
  669. &|IF (mem:=New(100))=NIL THEN error()|\cr
  670. Es una buena costumbre escribir entre par\'entesis cualquier expresi\'on de
  671. asignaci\'on que forme parte de otra, siempre que otras construcciones
  672. como |bla(a:=1)|, |b:=a:=1|,~\dots, no hayan eliminado la ambig\"uedad.
  673. \subsec Secuenciamiento (|BUT|\/).
  674. El operador de secuenciamiento |BUT| permite la escritura de dos expresiones
  675. en una construcci\'on que s\'olo permite una.  A menudo, al escribir
  676. expresiones\b/llamadas a funciones complejas, a uno le gustar\'{\i}a realizar una
  677. segunda cosa sobre la marcha, como una asignaci\'on.
  678. \Ejemplos
  679. \qquad Sintaxis:&\<exp1> |BUT| \<exp2>\cr
  680. implica: eval\'ua \<exp1>, pero retorna el valor de \<exp2>.
  681. \Ejemplos
  682. Ejemplo:&|mifunc((x:=2) BUT x*x)|\cr
  683. \finsma
  684. \item{} assigna  el  valor  2  a |x| y luego llama a mifunc con |x*x|.
  685. Los |()| entorno a la asignaci\'on son necesarios para impedir
  686. que el operador |:=| tome |2 BUT x*x| como expresi\'on.
  687. \subsec Reserva Din\'amica de Memoria (|NEW|\/).
  688. El operador |NEW| es un poderoso operador para la reserva din\'amica de
  689. memoria.  Supongamos que tenemos en alguna parte de nuestro c\'odigo
  690. |DEF p:PTR TO| \<cualquierobjeto> y |q:PTR TO INT|, entonces:
  691. \ejemplos
  692. &|NEW p|\cr
  693. es una expresi\'on que reservar\'a memoria para el tama\~no del objeto al que
  694. apunta |p|, y la inicializa con 0.  El puntero resultante se colocar\'a en
  695. |p|, adem\'as de ser el valor de la expresi\'on.  Si |NEW| no puede obtener la
  696. memoria, \'este lanzar\'a una excepci\'on |"NEW"|.  Por lo tanto, |NEW p| es
  697. practicamente equivalente a:
  698. \ejemplos
  699. &|IF (p:=New(SIZEOF cualquierobjeto))=NIL THEN Raise("MEM")|\cr
  700. con la diferencia de que |p| nunca recibe un valor si se lanza alguna
  701. excepci\'on, y que lo primero es evidentemente una expresi\'on, y no una
  702. sentencia.
  703. \noin Pero incluso hay m\'as: se pueden reservar arreglos din\'amicamente:
  704. \ejemplos
  705. &|NEW p[10]  -> arreglo de 10 objectos|\cr
  706. &|NEW q[a+1] -> arreglo de INT, con tama\~no calculado en ejecucion|\cr
  707. (esto no funciona al instanciar clases)
  708. \noin Algunas veces el problema de expresiones de lista |[1,2,3]| es que son
  709. est\'aticas, y al usar \'estas para construir estructuras de datos grandes ser\'{\i}a
  710. conveniente crearlas en tiempo de ejecuci\'on.  Se podr\'{\i}a utilizar el
  711. equivalente din\'amico de las listas:
  712. \ejemplos
  713. &|p:=[1,2,3]:cualquierobj        -> estructura estatica|\cr
  714. &|p:=NEW [1,2,3]:cualquierobj    -> !`reservado dinamicamente!|\cr
  715. Esto funciona tanto con listas como con listas con tipo, y tambi\'en con arreglos:
  716. \ejemplos
  717. &|NEW [1,2,3]       -> lista const, dinam. (nota: !`no como varlista!)|\cr
  718. &|NEW [1,2,3]:obj   -> objeto|\cr
  719. &|NEW [1,2,3]:INT   -> arrreglo de INTs|\cr
  720. \finsma
  721. La liberaci\'on de memoria reservada con cualquiera de las variaciones de
  722. |NEW| se realiza de forma autom\'atica al final del programa, o a mano con
  723. |END| o |FastDispose()|\nota{a excepci\'on de cuando se hab\'{\i}a utilizado |NEW|\<lista>,
  724. que necesita |FastDisposeList()|}.
  725. \noin Si usas |NEW [...]:|\<obj>, y el n\'umero de campos es menor que el
  726. que tiene el objeto, se a\~nadir\'an campos |0/NIL/"\0"| o lo que sea.  Esto nos
  727. permite extender los objetos sin tener problemas con reservas como estas.
  728. (f\'{\i}jate en que esto es diferente de las |[...]:|\<obj> est\'aticas)
  729. \noin Cuando usas |NEW| como sentencia, le pueden seguir un n\'umero
  730. indeterminado de punteros, por ejemplo, lo siguente es v\'alido:
  731. \ejemplos
  732. &|NEW a,b.create(),c|\cr
  733. \finsma
  734. \subsec Unificaci\'on (|<=>|\/).
  735. La unificaci\'on permite un estilo de programaci\'on totalmente diferente, y que
  736. te ser\'a familiar si estas acostumbrado a la programaci\'on L\'ogica (ProLog),
  737. ecuacional o funcional (Miranda\b/Gofer\b/Haskell).  La mayor\'{\i}a de nosotros,
  738. cuando usamos estructuras\b/arreglos para lo que sea, obtenemos valores de
  739. ellas por selecci\'on (|.| y |[]|), sin embargo, en esos lenguajes se usa un
  740. patr\'on de concordancias.  En~E:
  741. \<exp> |<=>| \<exp\_uni>
  742. \noin\<exp> puede ser cualquier expresi\'on, aunque en~v3 s\'olo es realmente
  743. \'util si es de alguna manera un puntero a una lista.  \<exp\_uni> es el
  744. patr\'on que se usa para hacer que concuerde (o unifique) \<exp>, las
  745. variables toman sus respectivos valores.  Si algo no concuerda, ninguna
  746. variable toma valor y la expresi\'on tiene como resultado |FALSE|\null{}.  En otro
  747. caso |TRUE|.
  748. \Ejemplos
  749. Ejemplo:&|a:=[1,2,3]|\cr
  750.         &| ....|\cr
  751.         &|IF a <=> [1,x,y] THEN ...|\cr
  752. \finsma
  753. Esto tendr\'a \'exito con |x=2| e |y=3|.  Si la lista tuviera otra longitud que
  754. no fuera 2, la unificaci\'on tambi\'en fallar\'{\i}a.  El echo de que |a| sea una lista
  755. es algo de lo que deber\'as asegurarte por t\'{\i} mismo, |EC| simplemente intentar\'a
  756. hacer que \<exp\_uni> encaje con el valor, sea cual sea, que obtenga de \<exp>.
  757. \Ejemplos
  758. Ejemplos |FALSE|:&|a <=> [1,x]     -> longitud de lista erronea|\cr
  759.                  &|a <=> [1,4,x]   -> 4=2 falla|\cr
  760.                  &|'bla' <=> [1,2] -> impredecible (?`caida del sistema?)|\cr
  761. \finsma
  762. Lo divertido de la unificaci\'on en que puedes hacer unificaciones realmente
  763. complejas, y que si tomas el primer campo (u otro) como constante, indicando
  764. el tipo de estructura que representa, tienes una buena forma de tipos
  765. din\'amicos.  !`Y todo el tiempo sin usar punteros!
  766. \noin Un ejemplo m\'as interesante:
  767. \ejemplos
  768. &|[BLA,[1,'burp'],['bla',"bla"]] <=> [BLA,[1,x],y]|\cr
  769. unifica:
  770. \ejemplos
  771. &|x='burp', y=['bla',"bla"]|\cr
  772. o incluso:
  773. \ejemplos
  774. &|IF miexp <=> [PLUS,[MUL,a,1],[SUBS,[PLUS,c,d],e]] THEN RETURN a+c+d-e|\cr
  775. \finsma
  776. Puede que sea un ejemplo tonto, pero uno se puede imaginar cosas como esta
  777. en el optimizador de c\'odigo de un compilador.  Es lo mismo que este
  778. fragmento de c\'odigo tradicional:
  779. \begintt
  780.    IF ListLen(miexp)=3
  781.      IF myexp[]=PLUS
  782.        IF ListLen(dummy:=miexp[1])=3
  783.          IF (dummy[]=MUL) AND (dummy[2]=1)
  784.            a:=dummy[1]
  785.            IF ListLen(dummy:=miexp[2])=3
  786.              IF dummy[]=SUBS
  787.                e:=dummy[2]
  788.                IF ListLen(dummy2:=dummy[1])=3
  789.                  IF dummy2[]=PLUS
  790.                    c:=dummy2[1]
  791.                    d:=dummy2[2]
  792.                    RETURN a+c+d-e
  793.                  ENDIF
  794.                ENDIF
  795.              ENDIF
  796.            ENDIF
  797.          ENDIF
  798.        ENDIF
  799.      ENDIF
  800.    ENDIF
  801. \endtt
  802. S\'olo que de una forma un poco m\'as \'optima.  Como ves, hay mucho poder
  803. expresivo entorno a la unificaci\'on comparada con la programaci\'on tradicional
  804. basada en selecci\'on.
  805. \noin De momento, lo \'unico permitido en la unificaci\'on son listas sin tipo,
  806. constantes (enteras), variables y Celdas-LISP\null{}.  En el futuro veremos esto
  807. ampliado a cadenas, listas con tipo\b/objetos, e incluso expresiones.
  808. \subsec Mutaci\'on de punteros (|::|\/).
  809. Cuando escribes una expresi\'on como ``|p|'', donde |p| es un |PTR TO| \<objeto>,
  810. \'este te permite referirte a \'el como tal.  El operador mutador de
  811. punteros te permite cambiar tal tipo en el momento (al vuelo):
  812. \ejemplos
  813. &|DEF p:PTR TO mp      -> puerto de mensajes|\cr
  814. \Esptab
  815. &|p.sigbit             -> accede a el|\cr
  816. &|p::ln.name           -> accede al puntero como si fuera un nodo|\cr
  817. \finsma
  818. Esto es muy \'util para punteros que pueden apuntar a diferentes tipos de
  819. cosas u objetos que forman parte de otros, cuando, por supuesto, s\'olo es
  820. posible una declaraci\'on.
  821. \noin Una segunda forma de uso es en |OBJECT|os que tienen miembros
  822. declarados como |LONG|, que en realidad son punteros.  Puedes darle un tipo
  823. al vuelo para hacer referencia a \'el de todas formas:
  824. \ejemplos
  825. &|miventana.userport::mp.sigbit|\cr
  826. \finsma
  827. Aqu\'{\i} el |OBJECT|o ventana tiene un |userport| definido como |LONG|, por lo que
  828. no podr\'as hacer referencia a \'el normalmente.
  829. \endchapter\saltacap
  830. \beginchapter Cap\'{\i}tulo 5. Sentencias
  831. Como se sugeri\'o en el cap\'{\i}tulo sobre el formato del c\'odigo E, generalmente una
  832. sentencia  se  declara en una l\'{\i}nea propia, aunque se pueden poner varias
  833. sentencias  en  un  misma  l\'{\i}nea  separ\'andolas con un punto y coma, de la
  834. misma  forma que una s\'ola sentencia se puede repartir entre varias l\'{\i}neas
  835. si se finaliza cada una de ellas con una coma ``|,|''.
  836. \Ejemplos
  837. Ejemplos:&|a:=1; WriteF('!`hola!\n')|\cr
  838.          &|DEF a,b,c,d,|\cr
  839.          &|    e,f,g|\cr
  840. \Ejemplos
  841. Las sentencias pueden ser:&$-$ asignaciones\cr
  842.                           &$-$ condicionales, |FOR| y similares.\cr
  843.                           &$-$ expresiones void\cr
  844.                           &$-$ etiquetas\cr
  845.                           &$-$ instrucciones en ensamblador\cr
  846. \finsma
  847. La coma es el principal caracter para indicar que no quieres finalizar
  848. la sentencia  con el  siguiente cambio  de l\'{\i}nea, aunque  a partir  de la
  849. versi\'on~3, cualquier elemento ({\it token}) que no pueda ir legalmente al final
  850. de una l\'{\i}nea provoca  la continuaci\'on de la sentencia.  Es m\'as, si no han
  851. sido  cerrados  todos  los  |[|  y |(|  de  una sentencia,  \'esta  tambi\'en
  852. continuar\'a en las siguientes l\'{\i}neas.
  853. \Ejemplos
  854. Ejemplos de tales elementos:     &|+ - * / =|\cr
  855.                                  &|< >= <=|\cr
  856.                                  &|:= . <=> ::          -> hay otros, pero|\cr
  857.                                  &|{ [ (                -> estos son los|\cr
  858.                                  &|AND OR BUT THEN IS   -> los mas utiles.|\cr
  859. Ejemplo de c\'odigo entre corchetes:&|a:=[|\cr
  860.                                   &|    [1,2],|\cr
  861.                                   &|    [3,4]|\cr
  862.                                   &|   ]     -> la asignacion finaliza aqui.|\cr
  863. \subsec Etiquetas y Saltos (|JUMP|\/).
  864. Las  etiquetas son  identificadores de  alcanze global  que incorporan
  865. |:|, como en:\qquad |mietiqueta:|
  866. \noin Se pueden utilizar con instrucciones como |JUMP|,  y para hacer referencia
  867. a  datos  est\'aticos.  Se pueden usar para salir de cualquier tipo de
  868. {\it bucle}\nota{aunque no recomiendo esta t\'ecnica.}, pero no de los procedimientos.
  869. En los programas~E normales se utilizan principalmente con el ensamblador
  870. \hbox{en-l\'{\i}nea}.  Las etiquetas siempre son visibles globalmente.
  871. \Ejemplos
  872. \qquad Sintaxis:&|JUMP |\<etiqueta>\cr
  873. \finsma
  874. Contin\'ua la  ejecuaci\'on en \<etiqueta>.  No es recomendable  usar esta
  875. instrucci\'on, est\'a disponible  para ser utlizada s\'olo en casos  en los que
  876. de otra forma se incrementar\'{\i}a la complejidad del programa.
  877. \Ejemplos
  878. Ejemplo:&|IF seacabo THEN JUMP termina|\cr
  879.         &|/* otras partes del programa */|\cr
  880. \Esptab
  881.         &|termina:|\cr
  882. \subsec Asiganci\'on (|:=|\/).
  883. La forma b\'asica de asignaci\'on es:
  884. \Ejemplos
  885. \qquad Sintaxis:&\<var>| := |\<exp>\cr
  886. \Ejemplos
  887. Ejemplos:&|a:=1,  a:=mifunc(),  a:=b*3|\cr
  888. \finsma
  889. En E se pueden asignar varias variables de una vez, cuando \<exp> es
  890. una funci\'on que devuelve varios valores de retorno.
  891. \subsec Mnemot\'ecnicos ensamblador.
  892. El ensamblador en-l\'{\i}nea es una parte real del lenguaje, no necesita
  893. introducirse mediante bloques especiales |"ASM"| o similares, como es normal
  894. en otros lenguajes, y tampoco necesita ensambladores independientes para
  895. ensamblar el c\'odigo.  Esto tambi\'en signifca que obedece las reglas de
  896. sintaxis de~E, etc.
  897. \noin Ejemplo:
  898. \begintt
  899. DEF a,b
  900. MOVEQ  #1,D0             /* algunas sentencias de ensamblador */
  901. MOVE.L D0,a              /* a:=1+b  */
  902. ADD.L  b,a
  903. WriteF('a=\d\n',a)       /* y escribira 3 */
  904. \endtt
  905. \subsec Conditionales (|IF|\/).
  906. \Ejemplos
  907. \qquad Sintaxis:&|IF |\<exp>| THEN |\<sentencia>| [ ELSE |\<sentencia>| ]|\cr
  908. \qquad o:       &|IF |\<exp>\cr
  909.          &|  |\<sentencias>\cr
  910.          &|[ ELSEIF |\<exp>|           /* puede haber varios ELSEIF */|\cr
  911.          &|  |\<sentencias>| ]|\cr
  912.          &|[ ELSE ]|\cr
  913.          &|  |\<sentencias>\cr
  914.          &|ENDIF|\cr
  915. \finsma
  916. Construye un bloque condicional.  Se\~nalar que hay dos formas generales
  917. para esta sentencia, una versi\'on de una l\'{\i}nea y la otra de varias.
  918. \subsec Para (|FOR|\/).
  919. \Ejemplos
  920. \qquad Sintaxis:&|FOR |\<var>| := |\<exp>| TO |\<exp>| STEP |\<paso>| DO |\<sentencia>\cr
  921. \qquad o:       &|FOR |\<var>| := |\<exp>| TO |\<exp>| STEP |\<paso>\cr
  922.          &|  |\<sentencias>\cr
  923.          &|ENDFOR|\cr
  924. \finsma
  925. Construye un bloque ``{\sl para}'', f\'{\i}jate en las dos formas generales. \<paso>
  926. puede ser  cualquier constante  positiva o negativa,  excluyendo 0,  y es
  927. opcional.
  928. \Ejemplos
  929. Ejemplo:&|FOR a:=1 TO 10 DO WriteF('\b\n',a)|\cr
  930. \finsma
  931. El cuerpo del |FOR| puede contener sentencias |EXIT|:
  932. \Ejemplos
  933. \qquad Sintaxis:&|EXIT| \<expbool>\cr
  934. que te permite salir del bucle si \<expbool> es cierta.
  935. \subsec Mientras (|WHILE|\/).
  936. \Ejemplos
  937. \qquad Sintaxis:&|WHILE |\<exp>| DO |\<sentencia>\cr
  938. \qquad o:       &|WHILE |\<exp>\cr
  939.          &|  |\<sentencias>\cr
  940.          &|ENDWHILE|\cr
  941. \finsma
  942. Construye  un  bloque  ``{\sl mientras}'', el cual se repite siempre que \<exp>
  943. sea  |TRUE|\null{}.   F\'{\i}jate en las diferencias entre la versi\'on de una-l\'{\i}nea\b/una-sentencia y la versi\'on
  944. de varias l\'{\i}neas.
  945. \noin |WHILE| tambi\'en puede contener sentencias |EXIT|, como el |FOR|.
  946. \subsec Repite (|REPEAT|\/).
  947. \Ejemplos
  948. \qquad Sintaxis:&|REPEAT|\cr
  949.          &|  |\<sentencias>\cr
  950.          &|UNTIL |\<exp>\cr
  951. \finsma
  952. Construye  un bloque ``{\sl repite-hasta}'' que se ejecutar\'a hasta que
  953. \<exp>|=TRUE|\null{}. (Se\~nalar que el bloque siempre se ejecutar\'a al menos una vez)
  954. \Ejemplos
  955. Ejemplo:&|REPEAT|\cr
  956.         &|  WriteF('?`Estas seguro, seguro de salir del programa?\n')|\cr
  957.         &|  ReadStr(stdout,s)|\cr
  958.         &|UNTIL StrCmp(s,'!`Si, por favor!')|\cr
  959. \finsma
  960. \subsec Bucle (|LOOP|\/).
  961. \Ejemplos
  962. \qquad Sintaxis:&|LOOP|\cr
  963.          &|  |\<sentencias>\cr
  964.          &|ENDLOOP|\cr
  965. \finsma
  966. Construye un bucle infinito.
  967. \subsec Selecci\'on (|SELECT|\/).
  968. \Ejemplos
  969. \qquad Sintaxis:&|SELECT |\<var>\cr
  970.          &|[ CASE |\<exp>\cr
  971.          &|  |\<sentencias>| ]|\cr
  972.          &|[ CASE |\<exp>\cr
  973.          &|  |\<sentencias>| ]   /* cualquier numero de bloques */|\cr
  974.          &|[ DEFAULT|\cr
  975.          &|  |\<sentencias>| ]|\cr
  976.          &|ENDSELECT|\cr
  977. \finsma
  978. Construye  un bloque de selecci\'on.  Se contrastar\'an varias expresiones
  979. con  la  variable, y s\'olo se ejecutar\'a el primer bloque que la satisfaga.
  980. El  bloque por omisi\'on (|DEFAULT|) se ejecutar\'a si la variable no satisface
  981. a ninguna de las expresiones.
  982. \Ejemplos
  983. Ejemplo:&|SELECT caracter|\cr
  984.         &|  CASE 10|\cr
  985.         &|    WriteF('Ejem, he encontrado un cambio de linea\n')|\cr
  986.         &|  CASE 9|\cr
  987.         &|    WriteF('!`Vaya, esto debe ser un tabulador!\n')|\cr
  988.         &|  DEFAULT|\cr
  989.         &|    WriteF('?`Conoces este: "\c" ?\n',caracter)|\cr
  990.         &|ENDSELECT|\cr
  991. \finsma
  992. Adem\'as de el ``|SELECT |\<var>'' de siempre, que trabaja con expresiones en
  993. las sentencias |CASE|, E~tiene un ``|SELECT |\<maxrango>| OF |\<exp>'' que funciona
  994. con  constantes  y/o  rangos  de  constantes  en el |CASE|\null{}.  No s\'olo es m\'as
  995. potente  para  muchas aplicaciones, si no que es mucho m\'as r\'apido para un
  996. n\'umero  de  casos grande (generalmente~|>5|), o si los casos son igualmente
  997. probables.   Sin  embargo  supone  que  todos los |CASE|s caen dentro de un
  998. rango  de  enteros peque\~no desde |0| a $n-1$, donde $n$ es un n\'umero razonable,
  999. por ejemplo |10|, o |255| para caracteres.
  1000. \Ejemplos
  1001. Ejemplo:&|SELECT 127 OF FgetC(stream)|\cr
  1002.         &|  CASE "\n","\b"|\cr
  1003.         &|    WriteF('fin de linea\n')|\cr
  1004.         &|  CASE "\t"," "|\cr
  1005.         &|    WriteF('espacio blanco\n')|\cr
  1006.         &|  CASE "0" TO "9"|\cr
  1007.         &|    WriteF('Entero\n')|\cr
  1008.         &|  CASE "A" TO "Z", "a" TO "z", "_"|\cr
  1009.         &|    WriteF('Identificador\n')|\cr
  1010.         &|  DEFAULT|\cr
  1011.         &|    WriteF('otros caracteres\n')|\cr
  1012.         &|ENDSELECT|\cr
  1013. |DEFAULT| se ejecutar\'a no s\'olo para aquellos valores para los que no hay
  1014. |CASE|, si no tambi\'en para los que est\'en fuera del rango, (en este ejemplo,
  1015. de |128| a |255| y |>255| o |<0|).
  1016. \noin Se\~nalar  que la  velocidad tiene  un precio:  ya que  este |SELECT|  usa
  1017. una  tabla de  saltos para  acceder  r\'apidamente al |CASE| correcto,  usar\'a
  1018. $2*$\<maxrango> bytes, |256| en este ejemplo.
  1019. \subsec Incremento (|INC/DEC|\/).
  1020. \Ejemplos
  1021. \qquad Sintaxis:&|INC |\<var>\cr
  1022.          &|DEC |\<var>\cr
  1023. \finsma
  1024. Es una abreviatura para \<var>|:=|\<var>|+1| y \<var>|:=|\<var>|-1|.  Con la \'unica
  1025. diferencia de que las primeras son sentencias y no retornan un valor.
  1026. \subsec Expresiones void (|VOID|).
  1027. \Ejemplos
  1028. \qquad Sintaxis:&|VOID |\<exp>\cr
  1029. \finsma
  1030. Calcula  la expresi\'on sin poner el resultado en lugar alguno.  S\'olo es
  1031. \'util  para  una  sintaxis  m\'as  clara,  ya  que en~E, de todas formas, las
  1032. expresiones  se  pueden usar como sentencias sin usar |VOID|\null{}.  Sin embargo,
  1033. esto  puede  causar  errores  dif\'{\i}ciles de apreciar, ya que, por ejemplo,
  1034. |a:=1|  asigna  el  valor  |1|  a  |a|,  pero |a=1| no resulta en nada como
  1035. sentencia.  E~te indicar\'a con una advertencia si eso ocurre.
  1036. \subsec Liberaci\'on de memoria (|END|).
  1037. |END| es  el complemento de |NEW|\null{}.  Cualquier puntero obtenido con  |NEW| se
  1038. debe liberar con ({\bf y s\'olo con}) |END|.
  1039. \Ejemplos
  1040. \qquad Sintaxis:&|END a|\cr
  1041. \qquad o incluso\cr
  1042.          &|END a,b,c|\cr
  1043. donde los  argumentos son  |PTR|s a alg\'un  tipo.  |END| libera el
  1044. espacio de memoria  al que se est\'a  apuntando, de forma que si  |a| es un
  1045. |PTR TO LONG|, s\'olo liberar\'a 4 bytes.  Esto quiere  decir que si reservaste
  1046. |a| con |NEW a[NUM]|, lo debes liberar con |END a[NUM]|.
  1047. \noin |NEW| acepta de  forma segura  punteros  |NIL|\null{}.  Los punteros tambi\'en  se
  1048. vuelven a |NIL| tras su liberaci\'on.
  1049. \noin Si |a|  es un |PTR| a  un objeto que es  un instancia de una  clase, |END|
  1050. obtendr\'a din\'amicamente  el tama\~no del objeto  que se desea liberar  de la
  1051. clase, de forma que si tienes un objeto de clase |b| de 32 bytes, pero el
  1052. puntero con el que lo vas a liberar es de una clase base (s\'olo 24 bytes),
  1053. |END| liberar\'a correctamente los 32 bytes.  Esto s\'olo funciona con clases.
  1054. \noin Puedes imaginar |END p| como una macro de:
  1055. \begintt
  1056.   p.end()
  1057.   FastDispose(p,p.classobject.virtuallen)
  1058.   p:=NIL
  1059. ENDIF
  1060. \endtt
  1061. Se\~nalar que |NEW| y |END| utilizan las funciones |FastNew()| y |FastDispose()|
  1062. (descritas en alg\'un otro cap\'{\i}tulo) que trabajan de forma bastante distinta a
  1063. como lo hacen |NewR()| y |Dispose()|.
  1064. \endchapter\saltacap
  1065. \beginchapter Cap\'{\i}tulo 6. Definici\'on\\y declaraci\'on\\de funciones
  1066.    Puedes usar |PROC| y |ENDPROC| para agrupar sentencias formando tus
  1067. propias funciones.  Tales funciones pueden tener cualquier n\'umero de
  1068. argumentos, y varios valores de retorno.
  1069. \Ejemplos
  1070. \qquad Sintaxis:&|PROC |\<etiqueta>| ( |\<args>|, ... )|\cr
  1071.          &|ENDPROC |\<valorretorno>|, ...|\cr
  1072. \finsma
  1073. Define  un  procedimiento  con  cualquier  n\'umero  de argumentos.  Los
  1074. argumentos  son  de tipo |LONG|, u opcionalmente de tipo |PTR TO |\<tipo> y no
  1075. necesitan ning\'un tipo de declaraci\'on.  Con |ENDPROC| se denota el final del
  1076. procedimiento.  Si no se d\'a un valor de retorno, se retorna 0.
  1077. \Ejemplos
  1078. Ejemplo:&funci\'on que retorna la suma de dos argumentos:\cr
  1079.         &    |  PROC suma(x,y)    /* x e y son variable locales */|\cr
  1080.         &    |  ENDPROC x+y       /* retorna el resultado  */|\cr
  1081. \esptab
  1082. m\'as corto:&|  PROC suma(x,y) IS x+y|\cr
  1083. \seccion Definiciones locales y globales: alcance (|DEF|\/).
  1084. Con la sentencia |DEF| puedes definir variables locales adicionales aparte
  1085. de aquellas que son argumentos.  La forma m\'as sencilla es con:
  1086. \ejemplos
  1087. &|DEF a,b,c|\cr
  1088. \finsma
  1089. que  declara  los  identificadores  |a|,  |b| y |c| como variables de tu funci\'on.
  1090. Se\~nalar que tales declaraciones deben estar al pricipio de tu funci\'on.
  1091. \Ejemplos
  1092. \qquad Sintaxis:&|DEF |\<declaraciones>|, ...|\cr
  1093. declara variables.  Una declaraci\'on tiene una de las siguiente formas:
  1094. \item{$-$} \<var> \qquad\qquad (que utilizaremos a partir de ahora.)
  1095. \item{$-$} \<var>|:|\<tipo> \qquad\qquad donde \<tipo>|=LONG, |\<identobjeto>,~\dots
  1096. \item{$-$} \<var>|[|\<tama\~no>|]:|\<type> \qquad\qquad donde \<tipo>|=ARRAY|, |STRING|, |LIST|
  1097. \espacio
  1098. Los argumentos de funciones se restringen a tipos b\'asicos.
  1099. La declaraci\'on de  un tipo b\'asico  puede tener una inicializaci\'on,  en
  1100. la versi\'on actual \'esta debe ser un entero (no una expresi\'on):
  1101. \ejemplos
  1102. &|DEF a=1,b=2|\cr
  1103. \finsma
  1104. Un  programa  est\'a  formado  por  un  conjunto  de funciones, llamados
  1105. procedimientos, |PROC|s.  Cada procedimiento puede tener variables Locales,
  1106. y  el programa como un todo puede tener variables Globales.  Al menos uno
  1107. de los procedimientos del programa debe ser el ``|PROC main()|'', ya que \'este
  1108. es el m\'odulo en el que comienza la ejecuci\'on.  Un programa sencillo puede
  1109. paracerse a:
  1110. \begintt
  1111. DEF a, b        /* definicion de variables globales */
  1112. PROC main()     /* las funciones en orden aleatorio */
  1113.   bla(1)
  1114. ENDPROC
  1115. PROC bla(x)
  1116.   DEF y,z       /* posiblemente variables locales propias */
  1117. ENDPROC
  1118. \endtt
  1119. \espacio
  1120. Para  resumir,  las  definiciones  locales  son  las  que  se hacen al
  1121. comienzo  de  los  procedimientos,  y que s\'olo son visibles dentro de esa
  1122. funci\'on.    Las  definiciones  globales  se  realizan  antes  del  primer
  1123. procedimiento,  de  tu  c\'odigo fuente, y son visibles globalmente.  Puede
  1124. haber variables locales con el mismo nombre que variables globales (y por
  1125. supuesto, lo mismo con variables locales de dos funciones diferentes), en
  1126. cuyo caso, las variables locales tienen prioridad.
  1127. \seccion ENDPROC/RETURN.
  1128. Como  se  indic\'o  con  anterioridad,  |ENDPROC| marca  el  final  de la
  1129. definici\'on de una funci\'on, y puede retornar un valor.  De forma opcional,
  1130. |RETURN|  se  puede  usar  en  cualquier punto de la funci\'on para salir de
  1131. ella, y si se usa en |main()| provocar\'a la finalizaci\'on del programa.
  1132. \Ejemplos
  1133. \qquad Sintaxis:&|RETURN [|\<valorretorno>|]|\cr
  1134. \finsma
  1135. Ejemplo:
  1136. \begintt
  1137. PROC obtenrecursos()
  1138.   /* ... */
  1139.   IF error THEN RETURN FALSE  /* algo fue mal ---> sal y falla */
  1140.   /* ... */
  1141. ENDPROC TRUE   /* llegamos hasta aqui, entonces retorna TRUE */
  1142. \endtt
  1143. \espacio
  1144. Una versi\'on reducida de la definici\'on de una funci\'on es:
  1145. \ejemplos
  1146. &|PROC |\<etiqueta>| ( |\<arg>|, ... ) RETURN |\<exp>\qquad (o |IS| en vez de |RETURN|)\cr
  1147. Estas  son  definiciones  de  funciones  que  s\'olo  realizan  peque\~nas
  1148. computaciones, como funciones factoriales y parecidas: ({\it one-liners} |:-)|)
  1149. \ejemplos
  1150. &|PROC fac(n) IS IF n=1 THEN 1 ELSE fac(n-1)*n|\cr
  1151. \seccion Funci\'on |main()|.
  1152. El  |PROC| llamado |main| tiene importancia porque es la primera funci\'on
  1153. que  se  ejecuta;  se  comporta como las dem\'as funciones, y tambi\'en puede
  1154. tener  variables locales.  |main()| no tiene argumentos:  los argumentos de
  1155. la  l\'{\i}nea  de  comandos  se  ofrecen  en  la variable de sistema |arg|, y
  1156. tambi\'en se pueden analizar con |ReadArgs()|.\nota{funci\'on de |dos.library|.}
  1157. \seccion Variables del sistema predefinidas.
  1158. Las siguientes variables globales siempre est\'an disponibles en tu programa,
  1159. se les llama variables del sistema.
  1160. \smallskip
  1161. \halign{{\tt#}\hfil&
  1162.          \quad\vtop{\parindent=0pt\hsize=24pc\hangindent=0pt\strut#\strut}\cr
  1163. arg&Como se dijo antes,  tiene un puntero a un cadena acabada
  1164.     en cero, con los argumentos de la l\'{\i}nea de comandos.
  1165.     No uses esta variable si prefieres usar |ReadArgs()|.\cr
  1166. stdout&Contiene el file-handle  para la salida estandard.  Si tu
  1167.        programa fue iniciado desde el Workbench, de forma que no
  1168.        hay  salida-de-shell  disponible,   |WriteF()|  abrir\'a  una
  1169.        ventana |CON:| para t\'{\i} y pondr\'a su file-handle en esta variable.\cr
  1170. stdin&file-handle para la entrada estandard.\cr
  1171. conout&Aqu\'{\i}  es  donde se pone el  file-handle,  y la ventana de
  1172.        consola se cerrar\'a de forma autom\'atica cuando tu programa
  1173.        finalice. (mira en |WriteF()| sobre la utilizaci\'on de estas dos
  1174.        variables de forma apropiada.)\cr
  1175. execbase,&Estas  cuatro  variables se ofrecen siempre inicializadas con el valor apropiado.\cr
  1176. dosbase,\cr
  1177. gfxbase,\cr
  1178. intuitionbase\cr
  1179. stdrast&Puntero al |rastport| standard para usarlo con tu programa,
  1180.         o |NIL|\null{}.  La usan las funciones gr\'aficas internas (|Line()|).\cr
  1181. wbmessage&Puntero a mensaje recibido si el programa se inici\'o desde
  1182.           Wb.  Se puede usar como booleano para detectar si el programa
  1183.           se inici\'o desde el Wb,  o para comprobar  cualquier
  1184.           argumento  que se seleccion\'o con \<|shift|> junto con el icono
  1185.           de la aplicaci\'on.  Mira |WbArgs.e| en directorio  |Src/Args/|
  1186.           para ver como utilizar de forma correcta esta variable.\cr
  1187. \seccion Argumentos por omisi\'on de funciones.
  1188. Los  argumentos  por omisi\'on permiten especificar un valor por omisi\'on
  1189. para  uno  o  m\'as  argumentos  de una funci\'on,  para el caso en el que la
  1190. funci\'on  se  llama  con menos argumentos que par\'ametros.  Por ejemplo, un
  1191. procedimiento como:
  1192. \ejemplos
  1193. &|PROC bla(a,b=1,c=NIL)|\cr
  1194. \ejemplos
  1195. se puede llamar con:&  que equivale a:\cr
  1196. \qquad| bla(a,b,c)|& |  bla(a,b,c)|\cr
  1197. \qquad| bla(a,b)|&   |  bla(a,b,NIL)|\cr
  1198. \qquad| bla(a)|&     |  bla(a,1,NIL)|\cr
  1199. \finsma
  1200. Esto  puede ser  muy  \'util, y  tambi\'en puede  expresar  algo sobre  la
  1201. funci\'on del procedimiento, por ejemplo, que la mayor\'{\i}a de las veces se le
  1202. llamar\'a  con |NIL|,  as\'{\i} que,  ?`por  qu\'e  no  suprimir ese argumento de  la
  1203. llamada por claridad?
  1204. \noin Esa tambi\'en es una raz\'on para no sobreutilizar los argumentos por
  1205. omisi\'on:  no empieces a dejar fuera valores no esenciales para los
  1206. procedimientos por mera pereza, si piensas que un parametro no tiene
  1207. realmente un valor por defecto.
  1208. \espacio
  1209. Para  impedir que  las llamadas  con menos  argumentos sean  amb\'{\i}guas,
  1210. s\'olo  pueden declararse  como arguementos  por omisi\'on  los \'ultimos  $0\ldots n$
  1211. par\'ametros de un |PROC| de $n$ par\'ametros.  Por ejemplo,\quad|PROC bla(a,b=1,c)| es ilegal
  1212. (!`aunque en esos casos siempre puedes reordenar los par\'ametros!).
  1213. \espacio
  1214. Los  argumentos que  se proporcionan  en  una llamada  se rellenan  de
  1215. izquierda a derecha, y los argumentos que falten se a\~naden con argumentos
  1216. por omisi\'on seg\'un sea necesario.
  1217. \seccion Valores de retorno m\'ultiples.
  1218. En E puedes retornar cualquier n\'umero de valores de retorno (m\'ax.~3 en
  1219. \E/ por razones de implementaci\'on). ?`C\'omo?
  1220. \Ejemplos
  1221. \qquad Sintaxis:&|RETURN [|\<exp>|,|\<exp>|,|\<exp>|]|\quad(o |ENDPROC|, por supuesto)\cr
  1222. \Ejemplos
  1223. Ejemplo:&|PROC sincos(rad)|\cr
  1224.         &|  DEF sin,cos|\cr
  1225.         &|  /* cualquier computacion necesaria */|\cr
  1226.         &|ENDPROC sin,cos|\cr
  1227. se llama con:
  1228. \ejemplos
  1229. &|s,c:=sincos(3.14)|\cr
  1230. &|s:=sincos(1.00)|\cr
  1231. \finsma
  1232. Como puedes ver, hay una nueva sentencia de la forma:
  1233. \ejemplos
  1234. &\<var>|, ... := |\<exp>\cr
  1235. donde \<exp> pr\'acticamente s\'olo tiene sentido como llamada a funci\'on.
  1236. \espacio
  1237. Se\~nalar dos cosas:
  1238. \item{$-$} Tu  decides el  n\'umero de  argumentos que  quieres recibir.  Esto tiene
  1239.   sentido  cuando  el primer  valor  de  retorno  es  el pricipal,  y  el
  1240.   segundo\b/tercero  representan  informaci\'on   adicional,  que  puede  ser
  1241.   importante s\'olo para algunos llamadores.
  1242. \item{$-$} Esta forma  es una  {\sl sentencia}.  Esto  significa que  cuando llamas  a
  1243.   |sincos()|  como parte  de  otra expresi\'on,  s\'olo se  usa  el primer  (el
  1244.   regular) valor de retorno:
  1245. \item{} |fun(sincos(1.0))|
  1246. \seccion Valores de funci\'on.
  1247. Con v3,  tambi\'en  puedes tener  funciones como  valores, y  usar \'estos
  1248. l\'{\i}bremente.  Son diferentes de las expresiones entrecomilladas, ya que se
  1249. llaman como los procedimientos normales.
  1250. \Ejemplos
  1251. Ejemplo:&|fun:={miproc}      -> obtener ptr a PROC|\cr
  1252.         &|  ....|\cr
  1253.         &|fun(1,2,3)         -> aplicar a args, como un PROC normal|\cr
  1254. \finsma
  1255. Notas:
  1256. \item{$-$} Debes  asegurarte de  que el |PROC|  del que tienes  el puntero  tiene el
  1257. mismo n\'umero de argumentos que los que le vas a aplicar.  El compilador
  1258. no puede comprobar esto por t\'{\i}.
  1259. \item{$-$} Peor  tadav\'{\i}a: debes  asegurarte de  que el puntero  es en  realidad un
  1260. puntero a |PROC|\null{}.  Hay una advertencia del compilador que te puede ayudar
  1261. con esto.
  1262. \endchapter\saltacap
  1263. \beginchapter Cap\'{\i}tulo 7. Declaraci\'on\\de constantes
  1264. \Ejemplos
  1265. \qquad Sintaxis:&|CONST |\<declaraciones>|, ...|\cr
  1266. te permite declarar una constante. Una declaraci\'on es como sigue:
  1267. \ejemplos
  1268. &\<ident>|=|\<valor>\cr
  1269. \finsma
  1270. Las constantes deben ir en may\'usculas, y el resto del program las trata como \<valor>.
  1271. \Ejemplos
  1272. Ejemplo:&|CONST MAX_LINEAS=100, ER_NOMEM=1, ER_NOFICHERO=2|\cr
  1273. \finsma
  1274. No  puedes declarar  constantes  en  t\'erminos de  otras  que se  est\'en
  1275. declarando en la misma sentencia |CONST|, debes ponerlas en la siguiente sentencia.
  1276. \noin Las declaraciones |CONST|, |ENUM| y |SET| siempre son globales, es decir, no
  1277. se pueden declarar constantes locales a un procedimiento.  El mejor lugar
  1278. para  poner las declaraciones de constantes es al principio de tu fuente,
  1279. aunque |EC| tambi\'en te permite ponerlas entre dos |PROC|s, por ejemplo.
  1280. \seccion Enumeraciones (|ENUM|).
  1281. Las  enumeraciones  son  un  tipo espec\'{\i}fico de constante al que no es
  1282. necesario darle valores, simplemente est\'an en un rango entre $0\ldots n$, siendo
  1283. la  primera  $0$.   De  todas  formas,  puedes utilizar |=|\<valor> en
  1284. cualquier punto de la enumeraci\'on para cambiar o reiniciar el contador de valores.
  1285. \Ejemplos
  1286. Ejemplos:&|ENUM CERO, UNO, DOS, TRES, LUNES=1, MARTES, MIERCOLES|\cr
  1287.          &|ENUM ER_NOFICHERO=100, ER_NOMEM, ER_NOVENTANA|\cr
  1288. \seccion Conjuntos (|SET|).
  1289. Los conjuntos son tambi\'en como  las enumeraciones, con la diferencia de
  1290. que en lugar de incrementar el valor ($0,1,2,\ldots$) incrementan el n\'umero de
  1291. bit ($0,1,2,\ldots$) resultando  en valores como ($1,2,4,8,\ldots$).  Esto tiene la
  1292. ventaja a\~nadida de  que se pueden usar como conjuntos  de banderas, tal y
  1293. como dice la palabra clave.
  1294. \noin Imag\'{\i}nate un conjunto como el siguiente para describir las propiedades
  1295. de una ventana:
  1296. \ejemplos
  1297. &|SET SIZEGAD,CLOSEGAD,SCROLLBAR,DEPTH|\cr
  1298. entonces, para inicializar una variable con las propiedades |DEPTH| y |SIZEGAD|:
  1299. \ejemplos
  1300. &|baderasvent:=DEPTH OR SIZEGAD|\cr
  1301. y para incluir una bandera |SCROLLBAR| adicional:
  1302. \ejemplos
  1303. &|baderasvent:=banderasvent OR SCROLLBAR|\cr
  1304. o para comprobar si alguna o ambas propiedades est\'an activas:
  1305. \ejemplos
  1306. &|IF banderasvetn AND (SCROLLBAR OR DEPTH) THEN  -> lo que sea|\cr
  1307. \seccion Constantes predefinidas.
  1308. Las siguientes son constantes predefinidas que se pueden usar en cualquier momento:
  1309. \ejemplos
  1310. |TRUE|,|FALSE|     & Representan los valores booleanos (|-1|,|0|).\cr
  1311. |NIL|&               (|=0|), el puntero sin incializar.\cr
  1312. |ALL|&               Con funciones de cadenas (|StrCopy()|) copia todos los caracteres.\cr
  1313. |GADGETSIZE|&        Tama\~no m\'{\i}nimo en bytes de un gadget (|Gadget()|).\cr
  1314. |OLDFILE|,|NEWFILE|&Par\'ametros de modo para usar con |Open()|.\cr
  1315. |EMPTY|&             Usado con m\'etodos (puede convertirse en palabra clave)\cr
  1316. |STRLEN|&            Tiene la longitud de la \'ultima cadena inmediata usada.\cr
  1317. &                    Ejemplo:\quad |Write(handle,'!`Hola colegas!',STRLEN)  -> =14|\cr
  1318. \endchapter\saltacap
  1319. \beginchapter Cap\'{\i}tulo 8. El Sistema\\de Tipos
  1320.    E  no  posee un sistema de tipos (o sistema de tipos de datos) r\'{\i}gido,
  1321. como  el  Pascal  o el Modula2, incluso es m\'as flexible que el sistema de
  1322. tipos del~C\null{}.  Esto debe tenerse bien en cuenta, junto con la filosof\'{\i}a de
  1323. que en~E todos los tipos de datos son iguales:  todos los valores b\'asicos
  1324. peque\~nos  como  caracteres,  enteros,~\dots,  tienen el mismo tama\~no de
  1325. 32~bits,  y  todos los dem\'as tipos de datos, como los arreglos y las cadenas
  1326. est\'an  representados  por punteros de 32~bits a ellos.  De esta forma, el
  1327. compilador de~E puede generar c\'odigo de una forma muy polim\'orfica.
  1328. \espacio
  1329. Las (des)ventajas son obvias:
  1330. \item{$-$} Menor control por parte del compilador sobre errores tontos.
  1331. \espacio
  1332. Ventajas:
  1333. \item{$-$} Polimorfismo a bajo nivel, crea facilmente potentes funciones gen\'ericas.
  1334. \item{$-$} Programaci\'on  flexible :  sin problemas con tipos de valores de retorno
  1335.            que no coinciden y sin {\it mutaciones} ni mensajes de error superfluos.
  1336. \item{$-$} Sin  errores dif\'{\i}ciles de encontrar al mezclar  tipos de datos de dife
  1337.            rentes tama\~nos.
  1338. \espacio
  1339. Veamos ahora los tipos de datos del lenguaje:
  1340. \seccion B\'asico (|LONG/PTR|).
  1341. S\'olo  hay  un tipo de variable b\'asico ---no complejo--- en E, el cual es
  1342. el tipo |LONG| de 32~bits.  Por ser el tipo por omisi\'on, se declarara con:
  1343. \Ejemplos
  1344. \qquad Sintaxis:&|DEF a:LONG|\qquad\qquad o simplemente:\quad |DEF a|\cr
  1345. \finsma
  1346. Este  tipo de  variable puede  contener lo  que se  conoce como  tipos
  1347. |CHAR|\b/|INT|\b/|PTR|\b/|LONG| en otros lenguajes.  Una variaci\'on especial de  |LONG| es
  1348. el  tipo  |PTR|\null{}.  Este tipo es compatible con |LONG|, con la \'unica diferencia
  1349. de que indica a qu\'e tipo apunta el puntero.  Por omisi\'on, el tipo |LONG| se
  1350. especifica como |PTR TO CHAR|.
  1351. \espacio
  1352. \Ejemplos
  1353. \qquad Sintaxis:&|DEF |\<var>|:PTR TO |\<tipo>\cr
  1354.                 &donde \<tipo> es o un tipo simple o uno compuesto.\cr
  1355. \Ejemplos
  1356. Ejemplo:&|DEF x:PTR TO INT, mipantalla:PTR TO screen|\cr
  1357. |screen|  es el nombre de un objeto definido en |intuition|\b/|screens.m|.
  1358. \espacio
  1359. Por ejemplo, si abres tu propia pantalla con:
  1360. \ejemplos
  1361. &|mipantalla:=OpenS(...) | etc.\cr
  1362. puedes  usar  el puntero |mipantalla| como en |mipantalla.rastport|.  Sin
  1363. embargo,  si  no  quieres  hacer  nada  con  la  variable  hasta llamar a
  1364. |CloseS(mipantalla)|, puedes declararla simplemente como:
  1365. \ejemplos
  1366. &|DEF mipantalla|\cr
  1367. \finsma
  1368. Las   declaraciones   de   variables   pueden  tener  inicializaciones
  1369. opcionales, pero s\'olo constantes enteras, no expresiones completas:
  1370. \ejemplos
  1371. &|DEF a=1, b=NIL:PTR TO textfont|\cr
  1372. \seccion Simple (|CHAR/INT/LONG|).
  1373. Los  tipos  simples  |CHAR|  (8bit) e |INT| (16bit) no se pueden usar como
  1374. tipos  para  una  variable  b\'asica.\nota{supongo que ya sabes la raz\'on.}  Sin
  1375. embargo, se pueden usar como tipo de dato para construir |ARRAY|s de ellos,
  1376. definir  punteros  a  ellos,  usarlos  en la definici\'on de |OBJECT|os, etc.
  1377. Mira los ejemplos de \'estos \'ultimos.
  1378. \seccion Arreglos (|ARRAY|).
  1379. Los arreglos de declaran indicando su longitud (en bytes):
  1380. \ejemplos
  1381. &|DEF b[100]:ARRAY|\cr
  1382. esto  define  un array de 100 bytes.  Internamente |b| es una variable de
  1383. tipo |LONG| y un puntero a esa \'area de memoria.
  1384. \espacio
  1385. El tipo  por omisi\'on de un  elemento de arreglo es  |CHAR|, aunque puede
  1386. ser cualquier cosa especificando:
  1387. \ejemplos
  1388. &|DEF x[100]:ARRAY OF LONG|\cr
  1389. &|DEF mismenus[10]:ARRAY OF newmenu|\cr
  1390. donde  |newmenu| es un ejemplo de estructura, llamados |OBJECT|os en~E\null{}.  El
  1391. acceso a los arreglos es muy sencillo, con \<var>|[|\<exps>|]|:
  1392. \ejemplos
  1393. &|b[1]:="a"|\cr
  1394. &|z:=mismenus[a+1].mutualexclude|\cr
  1395. \finsma
  1396. Se\~nalar que el \'{\i}ndice  de un arreglo de tama\~no $n$ se  mueve entre $0$ y
  1397. $n-1$, y no  entre $1$ y $n$.  Y tambi\'en que |ARRAY OF |\<tipo> es compatible
  1398. con |PTR TO |\<tipo>,  con la \'unica diferencia de que la  variable que es un
  1399. |ARRAY| se encuentra inicializada.
  1400. \seccion Complejo (|STRING/LIST|).
  1401. \item{$-$} Las cadenas (|STRING|), son similares a los arreglos,  aunque se
  1402.  diferencian  de  ellos  en  que  s\'olo  se pueden modificar usando funciones de
  1403.   cadenas de~E; y en que contienen informaci\'on sobre su longitud, de forma
  1404.   que las funciones de cadenas pueden modificarlas de una forma segura, es
  1405.   decir:  la cadena nunca puede crecer m\'as all\'a del \'area de memoria en la
  1406.   que est\'a.
  1407. \itemitem{} Declaraci\'on:\qquad |DEF s[80]:STRING|
  1408. \item{} El tipo de datos |STRING| (llamado cadenaE\nota{en realidad {\it estring}.}) es compatible con
  1409.   |PTR TO CHAR|, y tambi\'en con |ARRAY OF CHAR|, pero no en sentido opuesto.
  1410. \item{$-$} Las |LIST|as se pueden  entender como una mezcla entre |STRING|  y |ARRAY OF LONG|\null{}.
  1411.   Es  decir:  esta  estructura  de datos  mantiene  una  lista  de
  1412.   variables |LONG| que se puede extender y acortar como los |STRING|s.
  1413. \itemitem{} Declaraci\'on:\qquad |DEF x[100]:LIST|
  1414. \item{} Una  poderosa incorporaci\'on a este  tipo de  datos es  que tambi\'en  tiene un
  1415.   equivalente constante |[]|, de la misma  forma que los |STRING|s tienen |''|.
  1416.   Una lista es compatible con |PTR TO LONG|,  y por supuesto |ARRAY TO LONG|,
  1417.   aunque no en sentido contrario.
  1418. \seccion Compuesto (|OBJECT|).
  1419. Los |OBJECT| son como una estructura\b/clase en C/C++ o |RECORD| en Pascal.
  1420. \Ejemplos
  1421. Ejemplo:&|OBJECT miobj        -> define un estructura de datos|\cr
  1422.         &|  a:LONG            -> formada por tres elementos.|\cr
  1423.         &|  b:CHAR|\cr
  1424.         &|  c:INT|\cr
  1425.         &|ENDOBJECT|\cr
  1426. \Ejemplos
  1427. \qquad Sintaxis:&|OBJECT |\<nombreobj>\cr
  1428.                 &|  |\<nombremiembro>| [ : |\<tipo>| ]  -> cualquier numero|\cr
  1429.                 &|ENDOBJECT|\cr
  1430. donde \<tipo> es uno de los siguientes:
  1431. \ejemplos
  1432. &|CHAR/INT/LONG/|\<objeto>\cr
  1433. &|PTR TO CHAR/INT/LONG/|\<objeto>\cr
  1434. &|ARRAY OF CHAR/INT/LONG/|\<objeto>\cr
  1435. &(|ARRAY| es abreviatura de |ARRAY OF CHAR|)\cr
  1436. \finsma
  1437. Al igual que las declaraciones |DEF|, omitir el tipo implica |:LONG|.
  1438. \espacio
  1439. Destacar  que \<nombremiembro> no necesita ser un identificador \'unico y
  1440. puede aparecer en otros objetos.  Hay muchas formas de usar objetos:
  1441. \begintt
  1442. DEF x:miobj                  -> x es una estrutura
  1443. DEF y:PTR TO miobj           -> y es un puntero a la estrutura
  1444. DEF z[10]:ARRAY OF miobj
  1445. y:=[-1,"a",100]:miobj        -> listas con tipo
  1446. IF y.b="a" THEN /* ... */
  1447. z[4].c:=z[d+1].b++
  1448. \endtt
  1449. Los  elementos de los objetos se redondean a tama\~nos pares, y se ponen
  1450. en offsets pares:
  1451. \ejemplos
  1452. &|OBJECT micadena                   -> SIZEOF de micadena es 12|\cr
  1453. &|  longitud:CHAR, datos[9]:ARRAY   -> datos empieza con un offset de 2|\cr
  1454. &|ENDOBJECT|\cr
  1455. |PTR TO|  es el \'unico  tipo en |OBJECT|os  que puede hacer  referencia a
  1456. otros objetos que no hayan sido declarados todav\'{\i}a.
  1457. \Espacio
  1458. Podr\'{\i}a parecerte interesante echar un vistazo a las caracter\'{\i}sticas
  1459. de programaci\'on Orientada a Objetos de los |OBJECT|os.
  1460. \seccion Inicializaci\'on.
  1461. \item{$1.$} Siempre se inicializan a |NIL|\nota{siempre es mejor escribir  |=NIL|
  1462.            en definiciones de variables que se espera que sean |NIL|.}
  1463.            \ (u otra cosa si se indica)
  1464. \itemitem{$-$}Variables globales
  1465. \item{$2.$} Se inicializan a |''| y |[]| respectivamente
  1466. \itemitem{$-$} |STRING|s globales y locales
  1467. \itemitem{$-$} |LIST|as globales y locales
  1468. \item{$3.$} No se inicializan
  1469. \itemitem{$-$} variables locales (a no ser que se indique explicitamente)
  1470. \itemitem{$-$} |ARRAY|s globales y locales
  1471. \itemitem{$-$} |OBJECT|os globales y locales
  1472. \seccion Esencia del sistema de tipos de E.
  1473. Esta secci\'on intenta  explicar como funciona el sistema de  tipos de~E
  1474. desde otra perspectiva.
  1475. \Espacio
  1476. La  mayor  parte de los problemas que tiene la gente al programar en~E
  1477. provienen  de  una  visi\'on  incorrecta  del funcionamiento del sistema de
  1478. tipos  de~E\null{}. Por lo general se tiene una idea sobre el funcionamiento de
  1479. los   tipos   que   depende   del  lenguaje  de  programaci\'on  usado  con
  1480. anterioridad  y se intenta aplicarla a~E, lo que suele ser fatal, ya que~E
  1481. es bastante diferente en lo que se refiere a tipos.
  1482. \subsec El Sistema de Tipos.
  1483. E  es,  en  esencia,  un  lenguaje SIN-TIPOS\null{}.  De hecho, las variables
  1484. pueden  tener  un  tipo, aunque s\'olo sirve para indicar la forma de hacer
  1485. referencia  a  la  variable cuando se usa como puntero.  En practicamente
  1486. todas  las dem\'as construcciones del lenguaje las variables se tratan como
  1487. si todas tuvieran el mismo tipo, un valor sin tipo de 32~bits.
  1488. \noin En  la  pr\'actica  esto  significa que,  por  ejemplo,  excepto  expresiones
  1489. que  con los  operadores  |.|, |[]|  y  |++|,  todos los  operadores
  1490. y  funciones  trabajan  con  valores  de  32bits,  independiente  que  si
  1491. representan booleanos, enteros, reales o punteros a algo.
  1492. \subsec Tipos punteros.
  1493. En el sistema de tipos de E s\'olo hay 4 tipos, |PTR TO CHAR|, |PTR TO INT|,
  1494. |PTR TO LONG| y |PTR TO |\<objeto>,  donde \<objeto> es el nombre de un |OBJECT|o
  1495. definido  con anterioridad.  Cuando una variable (o miembro de un objeto
  1496. como  veremos  m\'as  tarde)  se  declara de este tipo, significa que si la
  1497. variable contiene un valor que es un puntero legal, esa es la forma de hacer
  1498. referencia a ella.
  1499. \subsec |LONG|, |ARRAY| etc.
  1500. Todos los  dem\'as tipos que podamos  ver en una declaraci\'on  |DEF| no son
  1501. tipos reales, ya que  no son m\'as que otras formas de  escribir uno de los
  1502. cuatro  anteriores.   Por ejemplo, |ARRAY OF |\<tipo> es otra forma de poner
  1503. |PTR TO |\<tipo>,  con la \'unica diferencia de que la primera recibe de forma
  1504. autom\'atica  la  direcci\'on  de  un  \'area  de  memoria  en  la  pila que es
  1505. suficientemente  grande  como  para  contener los datos para el n\'umero de
  1506. elementos especificado entre corchetes.
  1507. \noin Esta es una  tabla que muestra todos  los {\sl tipos} de E  en t\'erminos de
  1508. los cuatro b\'asicos:
  1509. \ejemplos
  1510. \qquad |ARRAY OF CHAR|, |ARRAY|, |STRING|, |LONG|&(equivale a)\quad |PTR TO CHAR|\cr
  1511. \qquad |ARRAY OF INT|&                            (equivale a)\quad |PTR TO INT|\cr
  1512. \qquad |ARRAY OF LONG|, |LIST|&                   (equivale a)\quad |PTR TO LONG|\cr
  1513. \qquad |ARRAY OF |\<objeto>, \<objeto>&           (equivale a)\quad |PTR TO |\<objeto>\cr
  1514. \finsma
  1515. \item{$-$} |LONG | son variables que no est\'an pensadas para ser usadas como puntero,
  1516.   por  ejemplo, enteros.  Su equivalencia  con  |PTR TO CHAR|  es  bastante
  1517.   l\'ogica,  ya que ambos hablan conceptualemente de cosas que  se miden en
  1518.   unidades de 1.  (por ejemplo, |++| tiene el mismo efecto en ambos)
  1519. \item{$-$} |LIST| y |STRING|  son lo mismo  que sus equivalentes en  |ARRAY| respecto al
  1520.   hecho  de  que  se  incializan  a  un  trozo  de  la  pila,  aunque  su
  1521.   representaci\'on  es  algo m\'as compleja para facilitar la comprobaci\'on de
  1522.   rango en tiempo de ejecuci\'on (cuando se usan con funciones apropiadas).
  1523. \item{$-$} un \<objeto> es equivalente a |[1]:ARRAY OF |\<objeto>.  Ambos  representan
  1524.   un |PTR TO |\<objeto> inicializado.
  1525. \espacio
  1526. Dentro de un |OBJECT| pueden aparecer estas mismas declaraciones, adem\'as
  1527. de  |CHAR|  e  |INT|,  y  no se permite declarar |LIST| ni |STRING|, ya que estos
  1528. \'ultimos  son  objetos complejos en s\'{\i} mismos, y no pueden formar parte de
  1529. un objeto.
  1530. \subsec Referencia.
  1531. Dado un puntero de alg\'un tipo,
  1532. \item{``|[]|''} puede indicar otros elementos  que est\'an ordenados secuencialmente a
  1533.      continuaci\'on del  elemento al que  el puntero est\'a apuntando  en ese
  1534.      momento.  Se\~nalar  que esto  permite  \'{\i}ndices  tanto positivos  como
  1535.      negativos,  y  tampoco se  hacen  suposiciones sobre donde y cuantos
  1536.      elementos se han reservado en realidad.
  1537. \item{``|++|''} hace que el puntero apunte al siguiente elemento en memoria,  y |--|
  1538.      al anterior.  Se\~nalar  que  estos operadores  siempre  act\'uan en  el
  1539.      puntero, y nunca sobre el elemento al que apuntan.
  1540. \item{``|.|''}  funciona  de  forma  similar a |[]|,  s\'olo que indexa el puntero por
  1541.      nombre, es decir, el puntero debe ser un |PTR TO |\<objeto>.
  1542. \espacio
  1543. |[]| y |.| se pueden concatenar a un puntero |p| en cualquier secuencia,
  1544. siempre que se sepa que el valor resultante anterior  es de nuevo de tipo
  1545. |PTR TO|.
  1546. \noin No  siempre  es  necesario  escribir  una  referencia  como  en  otros
  1547. lenguajes.   Por  ejemplo,  si |p| es un |ARRAY OF obj|, en lugar de escribir
  1548. |p[indice].miembro|  puedes escribir simplemente |p[indice]|, lo cual resulta
  1549. en  la  direcci\'on de ese objeto.  Esto tambi\'en explica porqu\'e |p[].miembro|
  1550. equivale  a  |p.miembro|,  ya  que  |p[]| es lo mismo que |p| cuando \'este
  1551. apunta a un objeto.
  1552. \subsec Sem\'atica de Referencia.
  1553. Otro concepto relacionado  con los tipos que hace a~E de alguna forma
  1554. diferente  de  otros lenguajes ---y por tanto dificil de entender---  es su
  1555. acento  en  la  Sem\'antica  de Referencia en vez de la Sem\'antica de Valor.
  1556. Intentar\'e argumentar aqu\'{\i} los benef\'{\i}cios de la primera.
  1557. \espacio
  1558. Informalmente, Sem\'antica de Referencia significa que los objetos en un
  1559. lenguaje  (principalmente  los que  no  son  simples  como los  |LONG|)  se
  1560. representan mediante punteros,  mientras que la Sem\'antica de Valor  trata
  1561. esos  objetos  como  si  fueran ellos mismos.  Un ejemplo de lenguaje que
  1562. s\'olo usa Sem\'antica de Valor es el BASIC, ejemplos de lenguajes que tienen
  1563. las  dos  son  lenguajes  del  tipo del C/C++ y del Pascal, y ejemplos de
  1564. lenguajes  con  s\'olo  Referencia  son  los  nuevos lenguajes Orientados a
  1565. Objetos, lenguajes funcionales como el LISP, y por supuesto~E.
  1566. \noin El uso de  Sem\'antica de Referencia no implica estar  ocupado todo el
  1567. tiempo con  punteros, es  m\'as, te  preocupar\'as de  ellos con  mucha menos
  1568. asiduidad que  en el caso de  lenguajes con sem\'antica mezclada  o el caso
  1569. con s\'olo valor,  debido principalmente a que la  mayor\'{\i}a de las estructuras
  1570. de datos  no triviales  se reservan  de forma  din\'amica, lo  cual implica
  1571. punteros.  El mejor ejemplo  de esto es el LISP,  en  el que  se programa
  1572. fuertemente con  punteros sin darse  cuenta.  En~E, uno se puede olvidar
  1573. facilmente de que |STRING| es un puntero,  debido a la facilidad con que se
  1574. puede pasar entre funciones; en~C son necesarias a veces gran cantidad
  1575. de~{\tt \&} cuando en  el equivalente en~E  no se necesitan, y  el equivalente en
  1576. Oberon de |bla('hola')|  se parece a |bla(sys.ADR('hola'))| debido  a que las
  1577. cadenas no representan un puntero, si no un valor como un todo~\dots
  1578. \endchapter\saltacap
  1579. \beginchapter Cap\'{\i}tulo 9. Funciones\\Predefinidas
  1580. \seccion Entrada/Salida.
  1581. \proto{WriteF(cadenaformato,args,...)}
  1582. \pproto{PrintF(cadenaformato,args,...)}
  1583. Imprime una cadena (que puede contener c\'odigos de formato)  en |stdout|.
  1584. Pueden incorporar  un n\'umero ilimitado  de argumentos.  Se\~nalar que, como
  1585. las  cadenas de  formato se  pueden  crear din\'amicamente,  no es  posible
  1586. cerciorarse de que el n\'umero de argumentos sea correcto.
  1587. \Ejemplos
  1588. Ejemplos:&|WriteF('!`Hola Mundo!\n') -> cadena con cambio de linea|\cr
  1589.          &|WriteF('a = \d \n',a)    -> escribe: "a = 123", si a era 123|\cr
  1590. \finsma
  1591. NOTA:  si, por ejemplo,  |stdout=NIL|  y tu programa fue iniciado  desde el
  1592. Workbench, |WriteF()|  crear\'a una ventana de  salida y pondr\'a el  handle en
  1593. |conout| y |stdout|.  Esa ventana se cerrar\'a de forma autom\'atica al salir del
  1594. programa despu\'es de que el usuario pulse \<{\rm return}>.  |WriteF()|  es la \'unica
  1595. funci\'on  que abre  esta ventana,  de  modo que  si quieres  hacer E/S  en
  1596. |stdout|, y  quieres estar seguro  de que |stdout<>NIL|,  haz un |WriteF('')|
  1597. como  primera instrucci\'on  de tu  programa  para asegurar  la salida.  Si
  1598. quieres  abrir la  ventana  de consola  por t\'{\i}  mismo,  debes hacerlo
  1599. poniendo  el handle  de fichero  resultante en  las variables  |stdout| y
  1600. |conout|, ya que  de esa forma la ventana se  cerrar\'a de forma autom\'atica
  1601. al finalizar el programa.  Si deseas cerrar esa ventana  de forma manual,
  1602. aseg\'urate de volver a poner |conout| de nuevo a~|NIL| para indicar a~E que
  1603. no hay una ventana de consola para cerrar.
  1604. \espacio
  1605. |PrintF()| es igual que |Write()|, s\'olo que utiliza E/S con buffers.  Ambas
  1606. retornan la longitud de la cadena que se acaba de imprimir.
  1607. \proto{Out(handlefich,car)}
  1608. \pproto{car:=Inp(handlefich)}
  1609. Escriben o  leen un s\'olo byte  a/de alg\'un fichero o |stdout|.  Si |car=-1|
  1610. entonces se  alcanz\'o el final del  fichero (|EOF|), o sucedi\'o  alg\'un error.
  1611. |Out()| retorna el  n\'umero de bytes que se escribieron  en realidad (si es
  1612. distinto de 1 entonces hubo un error).
  1613. \proto{long:=FileLength(cadenanombre)}
  1614. Determina  la  longitud del fichero que desees leer, y tambi\'en, si tal
  1615. fichero existe (retorna |-1| si hubo un error, o el fichero no existe).
  1616. \proto{ok:=ReadStr(handlefich,cadenae)}
  1617. {\it (mejor mira en el partado sobre ``Cadenas y funciones de cadenas''.)}
  1618. \proto{salant:=SetStdOut(nuevostdout)}
  1619. \pproto{entant:=SetStdIn(nuevostdin)}
  1620. Fija  la   variable  de  salida/entrada   estandard  |stdout|/|stdin|.
  1621. Equivale a :
  1622. \ejemplos
  1623. &|salant:=stdout|\cr
  1624. &|stdout:=newstdout|\cr
  1625. \seccion Cadenas y funciones de cadenas.
  1626. E tiene el tipo de datos |STRING|\null{}.  Este es una cadena,  que desde ahora
  1627. llamaremos  {\sl cadenaE}\nota{Estring.},  que  se puede  modificar  y cambiar  de
  1628. tama\~no,  al  contrario  que  las  {\it cadenas} normales,  que  es  como  nos
  1629. referiremos aqu\'{\i}  a cualquier secuencia  terminada en cero.  Las cadenasE
  1630. son compatibles con  las cadenas, aunque no en sentido  inverso, de forma
  1631. que si un argumento necesita una cadena,  podemos pasar cualquiera de las
  1632. dos.  Si se necesita una cadenaE,  no uses cadenas normales.
  1633. \Ejemplos
  1634. Ejemplos:&|DEF s[80]:STRING, n   -> s es una cadenaE de longitud max. 80|\cr
  1635.          &|ReadStr(stdout,s)     -> lee entrada desde la consola|\cr
  1636.          &|n:=Val(s)             -> recoge un numero de la cadenaE|\cr
  1637.          &|-> etc.|\cr
  1638. \finsma
  1639. Se\~nalar que todas  las funciones de cadenas manejan  de forma correcta
  1640. los casos en los que la cadena tiende a ser mayor que su longitud m\'axima:
  1641. \ejemplos
  1642. &|DEF s[5]:STRING|\cr
  1643. &|StrAdd(s,'Esta cadena es mayor de 5 caracteres',ALL)|\cr
  1644. &(|s| s\'olo contendr\'a |'Esta '|).\cr
  1645. \finsma
  1646. Las cadenas tambi\'en\nota{siempre debe comprobarse  si el puntero que retorna
  1647. esta funci\'on es |NIL|.} pueden reservarse  din\'amicamente en la memoria del
  1648. sistema con  |String()|.
  1649. \proto{s:=String(longmax)}
  1650. \ejemplos
  1651. &|DEF s[80]:STRING|\qquad  equivale a\qquad |DEF s|\qquad seguido de |s:=String(80)|\cr
  1652. \proto{bool:=StrCmp(cadena,cadena,long=ALL)}
  1653. Compara dos cadenas.  |long|\nota{|long| es un argumento por omisi\'on.} debe ser el n\'umero de caracteres a comparar,
  1654. o  |ALL|  si  queremos comparar la totalidad de la cadena.  Retorna
  1655. |TRUE| o |FALSE|.
  1656. \proto{StrCopy(cadenaE,cadena,long=ALL)}
  1657. Copia  |cadena|  en  |cadenaE|\null{}.  Si |long=ALL| copiar\'a toda la cadena.
  1658. Retorna la |cadenaE|
  1659. \proto{StrAdd(cadenaE,cadena,long=ALL)}
  1660. Igual que |StrCopy()|,  s\'olo que ahora la cadena se  concatena al final.
  1661. Retorna la |cadenaE|.
  1662. \proto{long:=StrLen(cadena)}
  1663. Calcula la longitud de cualquier cadena terminada en cero.
  1664. \proto{long:=EstrLen(cadenaE)}
  1665. Retorna la longitud de una |cadenaE|.
  1666. \proto{max:=StrMax(cadenaE)}
  1667. Retorna la longitud m\'axima de una |cadenaE|.
  1668. \proto{StringF(cadenaE,cadenafmt,args,...)}
  1669. Como  |WriteF()|,  pero  ahora  la salida va a |cadenaE| en vez de |stdout|.
  1670. Retorna la |cadenaE|, y su longitud como segundo valor de retorno.
  1671. \ejemplos
  1672. &|StringF(s,'resultado: \d\n',123)|\qquad en |s| tendremos ``|resultado: 123\n|''\cr
  1673. \proto{RightStr(cadenaE,cadenaE,n)}
  1674. Rellena la primera |cadenaE| con los \'ultimos |n| caracteres de la segunda.
  1675. Retorna la |cadenaE|.
  1676. \proto{MidStr(cadenaE,cadena,pos,long=ALL)}
  1677. Copia |long| caracteres (todos si |long=ALL|) desde la posici\'on |pos| de
  1678. |cadena| a |cadenaE|\null{}.  Retorna la |cadenaE|.
  1679. \Espacio
  1680. {\bf Nota importante}: en  todas las funciones relacionadas con cadenas  en las que
  1681. se usa una posici\'on de cadena, el primer caracter de la cadena est\'a en la
  1682. posici\'on 0, y no 1 como es com\'un en algunos lenguajes como el BASIC.
  1683. \proto{valor,leidos:=Val(cadena,leidos=NIL)}
  1684. Extrae el valor entero que representa la secuencia de caracteres \ASCII/
  1685. de la cadena.  No se tienen en cuenta los espacios\b/tabuladores,~\dots\enspace que le
  1686. precedan.  De esta forma  tambi\'en se  pueden  leer  n\'umeros hexadecimales
  1687. (|1234567890ABCDEFabcdef|) y binarios (|01|) si van precedidos de  |$| o  |%|
  1688. respectivamente.  Un menos  |-| puede indicar un  entero negativo.  |Val()|
  1689. tambi\'en retorna el n\'umero de caracteres leidos como segundo argumento, el
  1690. cual  debe  pasarse por referencia, o se puede recibir como segundo valor
  1691. de retorno.  Si |leidos| es 0 (|valor| ser\'a 0 tambi\'en) entonces la cadena
  1692. no conten\'{\i}a un entero, o el valor era muy grande para ponerlo en 32~bits.
  1693. |leidos| puede ser |NIL|.
  1694. \espacio
  1695. Ejemplos de cadenas que se analizan correctamente:
  1696. \ejemplos
  1697. &|'-12345',  '%10101010',  '  -$ABcd12'|\cr
  1698. Estos otros retornar\'an con |valor| y |leidos| igual a 0:
  1699. \ejemplos
  1700. &|'', 'hello!'|\cr
  1701. \proto{posbusc:=InStr(cadena1,cadena2,posinicial=0)}
  1702. Busca en |cadena1| la aparici\'on de |cadena2|,  probablemente partiendo  de
  1703. una posici\'on diferente de~0.  Retorna la posici\'on  en la que se hall\'o la
  1704. subcadena, o |-1| en otro caso.
  1705. \proto{nuevadircadena:=TrimStr(cadena)}
  1706. Retorna la  {\sl direcci\'on} del primer caracter de la cadena que no sea un
  1707. espacio, tabulador, etc~\dots
  1708. \proto{UpperStr(cadena)}
  1709. \pproto{LowerStr(cadena)}
  1710. Cambia la cadena de mayusculas o a min\'usculas.  Retorna una cadena.
  1711. \espacio
  1712. {\bf Nota importante}:  estas funciones cambian el contenido de la |cadena|, por lo
  1713. que  s\'olo  pueden  usarse con |cadenasE|, o cadenas que formen parte de los
  1714. datos  de  tu programa.  Esto quiere decir concretamente, que si obtienes
  1715. la direcci\'on de una cadena con una llamada a una funci\'on del sistema,
  1716. primero deber\'as  hacer  |StrCopy()|  a una cadena de tu programa, para
  1717. poder usar las funciones.
  1718. \proto{ok:=ReadStr(handlefich,cadenaE)}
  1719. Lee una cadena (acabada en \ASCII/ 10) de cualquier fichero o de |stdout|.
  1720. |ok| contendr\'a |-1| si ocurri\'o un error, o se alcanz\'o el |EOF|.
  1721. \noin Es importante que sepas que el contenido de la cadena leida hasta ese
  1722. momento sigue siendo v\'alido.  Se\~nalar tambi\'en que, al igual que |Inp()|,
  1723. |Out()|,~\dots\enspace esta funci\'on utiliza un estilo de |E/S| sin buffers, y por lo
  1724. tanto puede ser lenta.  La funci\'on de la dos.library |FGets()| es una buena
  1725. alternativa.
  1726. \proto{SetStr(cadenaE,nuevalong)}
  1727. Cambia manualmente la  longitud de  la  cadena.  S\'olo  es \'util  cuando
  1728. pones  datos  en  una  cadenaE  mediane  una  funci\'on  no  espec\'{\i}fica  de
  1729. cadenasE  y  quieres  seguir  utilizandola  como  cadenaE\null{}.  Por  ejemplo,
  1730. despu\'es de  usar una  funci\'on que simplemente  pone una  cadena terminada
  1731. en  cero   en  la   direcci\'on  de  la   cadenaE,  entonces   puedes  usar
  1732. |SetStr(micade,StrLen(micade))| para volverla manipulable  de nuevo.  Si la
  1733. cadena  es  demasiado larga,  |SetStr()|  no  har\'a  nada (aunque  eso  debe
  1734. evitarse siempre).
  1735. \proto{AstrCopy(cadena1,cadena2,tama\~no)}
  1736. {\it Array String Copy}  copia |cadena2| en el \'area de  memoria denotado por
  1737. |cadena1|.  |cadena1| no suele ser una cadenaE, sino un |ARRAY|\null{}. {\tt tama\~no} es el
  1738. n\'umero total de caracteres que puede contener |cadena1|, por ej., si es 5 y
  1739. |cadena2='holamundo'|, |cadena1| tendr\'a entonces |'hola'| + terminaci\'on en 0.
  1740. \proto{orden:=OstrCmp(cadena1,cadena2,max=ALL)}
  1741. {\it Ordered String Compare} retorna  |1|  si  |cadena2>cadena1|, |0|  si  son
  1742. iguales y |-1| si es menor.  S\'olo se camparan |max| caracteres.
  1743. \espacio
  1744. Puede que te sea interesante que heches un vistazo al apartado sobre
  1745. ``Enlace de cadenas''
  1746. \seccion Listas y funciones de listas.
  1747. Las listas son como las cadenas,  la \'unica diferencia es que est\'an
  1748. formadas por |LONG|s en lugar de |CHAR|s.  Tambi\'en pueden reservarse de forma
  1749. global, local o din\'amica.
  1750. \begintt
  1751. DEF milista[100]:LIST  -> local o global.
  1752. DEF a
  1753. a:=List(10)            -> dinamica. En este caso, 'a' puede ser NIL.
  1754. \endtt
  1755. De la misma forma que las cadenas se pueden representar con constantes
  1756. en expresiones, las listas tienen equivalentes constantes:
  1757. \ejemplos
  1758. &|[1,2,3,4]|\cr
  1759. el valor de tales expresiones es un puntero a una lista inicializada.  Una
  1760. caracter\'{\i}stica  que  tienen  estas  listas  es  que  pueden  tener partes
  1761. din\'amicas, es decir, partes que se completan en tiempo de ejecuci\'on:
  1762. \ejemplos
  1763. &|a:=3|\cr
  1764. &|[1,2,a,4]|\cr
  1765. incluso pueden tener otro tipo que no sea el |LONG| por omisi\'on, como:
  1766. \ejemplos
  1767. &|[1,2,3]:INT|\cr
  1768. &|[65,66,67,0]:CHAR                    -> equivalente a 'ABC'|\cr
  1769. &|['topaz.font',8,0,0]:textattr|\cr
  1770. &|OpenScreenTagList(NIL,[SA_TITLE,'MiPantalla',TAG_DONE])|\cr
  1771. \finsma
  1772. Como se ve  en los ejemplos anteriores, las  listas son extremadamente
  1773. \'utiles con funciones del sistema:  son compatibles con un |ARRAY OF LONG|,
  1774. y las  de objetos  con tipos  se pueden utilizar  en cualquier  lugar que
  1775. necesite  una estructura, o arreglo de ellas.  Las funciones de Taglist y
  1776. de n\'umero variable de argumentos se pueden utilizar de esta forma.
  1777. Sin embargo las funciones de listas  s\'olo funcionan con listas  de |LONG|,
  1778. las  listas con  tipos  s\'olo  son convenientes  para  la construcci\'on  de
  1779. estructuras de datos complejas y expresiones.
  1780. \espacio
  1781. Al igual que las cadenas, las listas mantienen cierta jeraqu\'{\i}a:
  1782. \ejemplos
  1783. &listas var. |->| listas const. |->| arreglos de long/puntero a long\cr
  1784. cuando  una  funci\'on  necesita un arreglo de |LONG|s puedes usar tranquilamente
  1785. una  lista  como argumento,  pero si la funci\'on necesita una lista
  1786. variable, o una lista constante, entonces no servir\'a un arreglo de LONGs.
  1787. \espacio
  1788. Es importante  entender el poder  de las listas,  y en  particular las
  1789. listas con tipo:  \'estas pueden evitar una buena cantidad  de problemas en
  1790. la construcci\'on de pr\'acticamente cualquier estructura  de datos.  Intenta
  1791. usar las listas en tus propios programas, y observa la funci\'on que tienen
  1792. en los programas de ejemplo.
  1793. \espacio
  1794. \Ejemplos
  1795. Resumen:\cr
  1796. \qquad\qquad|[|\<elem>,\<e>,...| ]|        &lista inmediata (|LONG|s, con funcs. de listas)\cr
  1797. \qquad\qquad|[|\<elem>,\<e>,...| ]:|\<tipo>&lista con tipos (para crear estruct. de datos)\cr
  1798. Si \<tipo>  en un tipo simple  como |INT| o  |CHAR|, lo que obtienes  es un
  1799. equivalente inicializado de un |ARRAY OF |\<tipo>, si \<tipo> es un nombre de
  1800. objeto, estar\'as construyendo objetos  inicializados, o |ARRAY OF |\<objeto>,
  1801. dependiendo de la longitud de la lista.
  1802. \espacio
  1803. Si escribes\quad |[1,2,3]:INT|\quad crear\'as una estructura de 6~bytes,  de
  1804. 3~valores de 16~bits  para ser m\'as preciso.  El valor de esta expresi\'on es,
  1805. entonces,  un puntero  a ese  \'area de  memoria.  Lo mismo ocurre  si, por
  1806. ejemplo, tienes un objeto como este:
  1807. \ejemplos
  1808. &|OBJECT miobjeto|\cr
  1809. &\qquad|a:LONG, b:CHAR, c:INT|\cr
  1810. &|ENDOBJECT|\cr
  1811. escribir\quad |[1,2,3]:miobjeto|\quad implicar\'a  la  creaci\'on  de una estructura de
  1812. datos  en memoria de 8~bytes, siendo los cuatro primeros bytes un |LONG| de
  1813. valor~1,  el siguiente byte un |CHAR| de valor~2, luego un byte relleno, y
  1814. los dos \'ultimos un |INT| (2bytes) de valor~3.  Tambi\'en podr\'{\i}as escribir:
  1815. \ejemplos
  1816. &|[1,2,3,4,5,6,7,8,9]:myobject|\cr
  1817. y  estar\'{\i}as  creando  un |ARRAY OF miobjeto| de tama\~no~3.  F\'{\i}jate que tales
  1818. listas  no tienen porqu\'e ser completas (con 3,6,9,\dots\enspace elementos),  puedes
  1819. crear objetos parciales con listas de cualquier tama\~no.
  1820. \espacio
  1821. Un \'ultimo  apunte sobre  el tama\~no  de los datos:  en el  Amiga puedes
  1822. depender del hecho de que una  estructura como |miobjeto| tiene un tama\~no
  1823. de 8~bytes,  y que tiene un byte de  relleno para obtener  alineaci\'on de
  1824. palabras (16~bit). Sin embargo, es bastante probable que un compilador de~E
  1825. para  arquitecturas |80x86| no  usar\'{\i}a el byte  de relleno y  crear\'{\i}a una
  1826. estructura de  7~bytes, y  que un compilador  de~E para  una arquitectura
  1827. |sun-sparc|,  si no  me equivoco,  intentar\'{\i}a alinear  los datos  a palabras
  1828. dobles  (32~bits),  creando  una estructura  de~10  o  12~bytes.  Algunos
  1829. microprocesadores  (son raros,  pero existen)  incluso usar\'{\i}an  (|36:18:9|)
  1830. como  n\'umero de  bits para  sus tipos  (|LONG:INT:CHAR|), en  lugar de  los
  1831. (|32:16:8|) a  los que  estamos habituados.  Con esto  quiero decir  que no
  1832. hagas  muchas suposiciones  sobre la  estructura  de los  |OBJECT|os y  las
  1833. |LIST|as si  quieres escribir  c\'odigo que tenga  alguna oportunidad  de ser
  1834. portable y que no dependa de efectos laterales.
  1835. \proto{ListCopy(listavar,lista,num=ALL)}
  1836. Copia |num| elementos de |lista| a |listvar|.  Retorna |listavar|.
  1837. \Ejemplos
  1838. Ejemplo:&|DEF milista[10]:LIST|\cr
  1839.         &|ListCopy(milista,[1,2,3,4,5],ALL)|\cr
  1840. \proto{ListAdd(listavar,lista,num=ALL)}
  1841. Copia |num| elementos de |lista| en la cola de |listavar|. Retorna |listavar|.
  1842. \proto{ListCmp(lista,lista,num=ALL)}
  1843. Compara dos listas, o una parte de ellas.
  1844. \proto{long:=ListLen(lista)}
  1845. Retorna la longitud de |lista|, ej: |ListLen([a,b,c])| retornar\'{\i}a 3.
  1846. \proto{max:=ListMax(listavar)}
  1847. Retorna la longitud m\'axima posible de |listavar|.
  1848. \proto{valor:=ListItem(lista,indice)}
  1849. Opera como\quad |value:=list[indice]|\quad con la diferencia de que |lista|
  1850. puede ser un valor constante en vez de un puntero.  Esto es bastante \'util
  1851. en situaciones  como  la siguiente  en  la que queremos usar una lista de
  1852. valores directamente:
  1853. \ejemplos
  1854. &|WriteF(ListItem(['!`vale!','!`sin mem!','!`no fichero!'],error))|\cr
  1855. que imprime un mensaje de error dependiendo de |error|.  Equivale a:
  1856. \ejemplos
  1857. &|DEF temp:PTR TO LONG|\cr
  1858. &|temp:=['!`vale!','!`sin mem!','!`no fichero!']|\cr
  1859. &|WriteF(temp[error])|\cr
  1860. \finsma
  1861. \proto{SetList(listavar,nuevalong)}
  1862. Cambia la longitud de la lista de forma manual.  S\'olo ser\'a \'util cuando
  1863. leas informaci\'on en la lista con una  funci\'on  que no sea espec\'{\i}fica para
  1864. listas, y quieres seguir utilizandola como una lista de verdad.
  1865. \Espacio
  1866. Puede que te resulte interesante, mirar las funciones de listas con expresiones
  1867. entrecomilladas as\'{\i} como las funciones de enlace de listas.
  1868. \seccion Intuition.
  1869. \proto{ptrv:=OpenW(x,y,ancho,alto,IDCMP,wflags,tit,pant,sflags,gads,tagl=NIL)}
  1870. Crea una ventana  donde |wflags| son los flags de  caracter\'{\i}sticas de la
  1871. ventana (como  |BACKDROP|, |SIMPLEREFRESH|,~\dots, generalmente |$F|)  y |sflags| son
  1872. los que indican el tipo de pantalla en la que se abrir\'a la ventana (1=wb,
  1873. 15=propia).  Si |sflags=15| entonces es necesario que  |pant| sea un puntero v\'alido,
  1874. en  otro  caso  sirve  |NIL|\null{}.  |gads|  puede  apuntar  a una
  1875. estrutura |glist| que  puedes crear f\'acilmente con la  funci\'on |Gadget()|, en
  1876. otro caso |NIL|.
  1877. \proto{CloseW(ptrv)}
  1878. Cierra la ventana de nuevo.  La \'unica diferencia  con |CloseWindow()| es
  1879. que acepta punteros |NIL|, y que vuelve a poner |stdrast| a |NIL|.
  1880. \proto{ptrp:=OpenS(ancho,alto,planos,sflags,titulo,taglist=NIL)}
  1881. Crea una pantalla propia.  |planos|=n\'umero de bitplanes (|1-6|, \'o |1-8| en AGA).
  1882. \proto{CloseS(ptrp)}
  1883. Igual que |CloseW()|, s\'olo que para pantallas.
  1884. \proto{buffersig:=Gadget(buffer,listag,id,flags,x,y,ancho,cadena)}
  1885. \pproto{{\it Atenci\'on: esta funci\'on est\'a un poco anticuada.}}
  1886. Esta funci\'on  crea una lista  de gadgets,  los cuales se  pueden luego
  1887. incluir  en  t\'u  ventana  pas\'andola  como  argumento  a  |OpenW()|,  o
  1888. posteriormente con funciones de Intuition como |AddGlist()|.
  1889. \noin |buffer| es por lo general un |ARRAY|  de al menos |GADGETSIZE| bytes para
  1890. mantener todas  las estructuras asociadas  con un gadget, |id|  es n\'umero
  1891. identificador que nos ayudar\'a a  recordar el gadget pulsado cuando llegue
  1892. un IntuiMessage.  |flags| puede ser: 0=gadget normal, 1=gadget booleano,
  1893. 3=gadget booleano seleccionado.  |ancho| es el ancho en  pixels,  y  debe
  1894. ser lo  suficientemente grande como para acoger |cadena|, la  cual estar\'a
  1895. centrada autom\'aticamente.  |listag| debe ser |NIL| para el primer gadget, y
  1896. varlistag para todos los dem\'as, para que~E pueda enlazar los gadgets.
  1897. \noin La funci\'on retorna un puntero al siguente buffer (|=buffer+GADGETSIZE|).
  1898. \noin Ejemplo para tres gadgets:
  1899. \begintt
  1900. CONST MAXGADGETS=GADGETSIZE*3
  1901. DEF   buf[MAXGADGETS]:ARRAY, sigui, ptrv
  1902. sigui:=Gadget(buf,NIL,1,0,10,20,80,'bla')   -> el 1er gadget
  1903. sigui:=Gadget(sigui,buf,... )
  1904. sigui:=Gadget(sigui,buf,... )               -> enlaza gadgets
  1905. ptrv:=OpenW( ...,buf)
  1906. \endtt
  1907. \proto{codigo:=Mouse()}
  1908. Retorna el  estado actual  de los  2 o 3  botones del  rat\'on; izqdo=1,
  1909. dcho=2  y  central=4.  Si, por  ejemplo,  codigo=3  querr\'a decir  que  se
  1910. pulsaron los botones izquierdo y derecho a la vez.
  1911. \espacio
  1912. {\bf Importante}: Esta  no es una funci\'on  real de Intuition,  si quieres conocer los
  1913. eventos  del  rat\'on de  una  forma  correcta,  tendr\'as que  analizar  los
  1914. |IntuiMessage| que  reciba tu ventana.  Esta es la  \'unica funci\'on de~E que
  1915. utiliza el  hardware directamente,  y por tanto s\'olo es  aconsejable para
  1916. programas  de  tipo demo,  o  para  pruebas.  ({\bf No  uses esta  funcion  en
  1917. programas que se supone van a funcionar bajo el SO}).
  1918. \proto{bool:=LeftMouse(ven)}
  1919. \pproto{WaitLeftMouse(ven)}
  1920. Alternativa de Intuition a |Mouse()|, comprueban la pulsaci\'on del rat\'on.
  1921. \proto{x:=MouseX(ven)}
  1922. \pproto{y:=MouseY(ven)}
  1923. Permite leer la posici\'on del rat\'on.  Coordenadas relativas a la ventana |ven|.
  1924. \proto{clase:=WaitIMessage(ventana)}
  1925. Esta funci\'on hace m\'as f\'acil la espera de un evento de ventana.  Espera
  1926. la llegada de un |IntuiMessage| y retorna la clase del evento. Guarda otros
  1927. datos como |codigo| y |calificadores| en variables globales privadas, que
  1928. pueden leerse con las siguientes funciones.  |WaitIMessage()|  equivale  al
  1929. siguiente fragmento de c\'odigo:
  1930. \begintt
  1931. PROC waitimessage( ven:PTR TO window )
  1932.   DEF puerto,mens:PTR TO intuimessage,clase,codigo,calif,diri
  1933.   puerto:=ven.userport
  1934.   IF (mens:=GetMsg(puerto)) = NIL
  1935.     REPEAT
  1936.       WaitPort(puerto)
  1937.     UNTIL (mens:=GetMsg(puerto)) <> NIL
  1938.   ENDIF
  1939.   clase:=mens.class
  1940.   codigo:=mens.code             /* almacenado internamente */
  1941.   calif:=mens.qualifier
  1942.   diri:=mens.iaddress
  1943.   ReplyMsg(mens)
  1944. ENDPROC clase
  1945. \endtt
  1946. como  puedes  ver,  recoge  exactamente  un  mensage,  y  no se olvida de
  1947. m\'ultiples  mensajes que llegan en el mismo evento, si se llama m\'as de una
  1948. vez.   Digamos, por ejemplo, que has abierto una ventana que muestra algo
  1949. y simplemente espera a que la cierres (s\'olo indicaste |IDCMP_CLOSEWINDOW|):
  1950. \ejemplos
  1951. &|WaitIMessage(miventana)|\cr
  1952. o  puedes  tener  un  programa  que  espere por m\'as tipos de eventos, que
  1953. controlar\'{\i}as en un bucle, y finaliza con un evento |CLOSEWINDOW|:
  1954. \ejemplos
  1955. &|WHILE (clase:=WaitIMessage(ven))<>IDCMP_CLOSEWINDOW|\cr
  1956. &|  /* trata otras clases */|\cr
  1957. &|ENDWHILE|\cr
  1958. \finsma
  1959. \proto{codigo:=MsgCode()}
  1960. \pproto{calif:=MsgQualifier()}
  1961. \pproto{diri:=MsgIaddr()}
  1962. Proporcionan  las  variables globales privadas mencionadas antes.  Los
  1963. valores   que   retornan   son   los   definidos  durante  la  llamada  a
  1964. |WaitIMessage()| m\'as reciente.
  1965. \Ejemplos
  1966. Ejemplo:&|IF clase:=IDCMP_GADGETUP|\cr
  1967.         &|  migadget:=MsgIaddr()|\cr
  1968.         &|  IF migadget.userdata=1 THEN ... -> el usuario pulso gadget 1|\cr
  1969.         &|ENDIF|\cr
  1970. \seccion Gr\'aficos.
  1971. Todas  las funciones  gr\'aficas de  apoyo que  requieren expl\'{\i}citamente
  1972. un  rastport   utilizan  la  variable  de   sistema  |stdrast|,  definida
  1973. autom\'aticamente en la  \'ultima llamada a |OpenW()| o |OpenS()|,  y que toma el
  1974. valor |NIL|  con |CloseW()| y |CloseS()|.  Se puede llamar a  estas dos \'ultimas
  1975. funciones  cuando |stdrast|  a\'un  es |NIL|\null{}.  Se  le puede  dar  un valor  a
  1976. |stdrast| manualmente con |SetStdRast()| o |stdrast:=mirastport|.
  1977. \proto{Plot(x,y,color=1)}
  1978. Dibuja un  s\'olo punto en  tu pantalla/ventana  con uno de  los colores
  1979. disponibles.  El n\'umero del color va desde |0...31|, o~|0...255| bajo AGA.
  1980. \proto{Line(x1,y1,x2,y2,color=1)}
  1981. Dibuja una l\'{\i}nea.
  1982. \proto{Box(x1,y1,x2,y2,color=1)}
  1983. Dibuja un rect\'angulo o caja.
  1984. \proto{Colour(dibujo,fondo=0)}
  1985. Fija los  colores\nota{las funciones que necesitan un {\it color} cambian el |Apen| de |stdrast|.}
  1986. para todas  las funciones gr\'aficas (de  la librer\'{\i}a)
  1987. que necesiten  un color como argumento.  Este es el {\sl registro}  del color
  1988. (por ejemplo, de |0...31|) y no el {\sl valor} del color.
  1989. \proto{TextF(x,y,cadenaformato,args,...)}
  1990. Exactamente igual que |WriteF()|, s\'olo que escribe en alg\'un (x,y)  de tu
  1991. |stdrast|,  en lugar de hacerlo a |stdout|.  Retorna la longitud de la cadena
  1992. resultante.
  1993. \proto{rastant:=SetStdRast(rastnuevo)}
  1994. Cambia el rastport de salida de las funciones gr\'aficas de E.
  1995. \proto{SetTopaz(tama\~no=8)}
  1996. Te permite fijar la fuente del rastport |stdrast| a topaz, simplemente
  1997. para  asegurarte  de que alguna fuente propia no desfigure la composici\'on
  1998. de la ventana.  Por supuesto, |tama\~no| puede ser 8 o 9.  Est\'a para usarse
  1999. como \'ultimo recurso si no permites sensibilidad a fuentes.
  2000. \proto{SetColour(pantalla,regcolor,r,g,b)}
  2001. Fija el registro de color (|0...255|)  de la pantalla a cierto valor {\sc RGB}.
  2002. Cada valor de {\sc RGB} puede oscilar entre |0...255|, es decir, color de 24~bits.
  2003. Esta  funci\'on reescalar\'a el color de forma autom\'atica si no se dispone de
  2004. un modo AGA, utilizando la funci\'on apropiada.
  2005. \seccion Sistema.
  2006. \vskip-\medskipamount
  2007. \proto{bool:=KickVersion(vers)}
  2008. Retornar\'a |TRUE|  si el KickStart de la m\'aquina en que est\'a corriendo tu
  2009. programa es igual o superior a |vers|, en otro caso |FALSE|.
  2010. \proto{mem:=New(n)}
  2011. Esto  crea din\'amicamente un arreglo (\'area de memoria, si lo prefieres)
  2012. de |n|~bytes.  Se diferencia de |AllocMem()| en que se llama de forma autom\'atica
  2013. con flags |$10000| (es decir, memoria inicializada a zero de cualquier
  2014. tipo),  y en que no es necesario llamar a |Dispose()|, ya que est\'a enlazada
  2015. a una lista de memoria {\sl liberada autom\'aticamente} al finalizar el programa.
  2016. \proto{mem:=NewR(n)}
  2017. Igual que  |New()|, solo que ahora  alcanza la excepci\'on |"MEM"|  de forma
  2018. autom\'atica en lugar de retornar cuando no hay suficiente memoria.
  2019. \proto{mem:=NewM(n,flags)}
  2020. Igual que |NewR()|, y adem\'as permite especificar flags (|MEMF_CHIP| etc.)
  2021. \proto{Dispose(mem)}
  2022. Libera memoria reservada con |New()|.  S\'olo es necesaria cuando quieras liberar memoria
  2023. de forma expl\'{\i}cita  {\it durante} el programa, ya que, al final del programa se
  2024. libera toda la memoria.
  2025. \proto{CleanUp(valorret=0)}
  2026. Finaliza el programa en cualquier punto.  Substituye al |Exit()|
  2027. de  DOS:  !`nunca uses |Exit()|!,  utiliza |CleanUp()| en su lugar,  ya que
  2028. libera la memoria, cierra las librerias correctamente,~\dots \enspace |valorret| se
  2029. da  al  DOS  como  c\'odigo  de retorno.  S\'olo se necesita |CleanUp()| cuando
  2030. hay que finalizar el programa en un punto diferente al |ENDPROC| de |main()|.
  2031. \proto{cantidad:=FreeStack()}
  2032. Retorna la cantidad de espacio libre que hay en la pila.  Que debe ser
  2033. siempre  1000  o superior.  No debes preocuparte de tal cantidad mientras
  2034. no utilice recursiones profundas.
  2035. \proto{bool:=CtrlC()}
  2036. Retorna |TRUE| si se ha pulsado |Ctrl-C| desde la \'ultima comprobaci\'on,  en
  2037. otro caso  |FALSE|\null{}.  S\'olo funciona en programas  que se est\'an ejecutando en
  2038. una consola, es decir, programas de |CLI|.
  2039. \noin Ejemplo de uso de las tres \'ultimas funciones:
  2040. \begintt
  2041. -> calcular el factorial de un argumento de la linea de comandos
  2042. OPT STACK=100000
  2043. PROC main()
  2044.   DEF num, r
  2045.   num:=Val(arg,{r})
  2046.   IF r=0
  2047.     WriteF('args erroneos.\n')
  2048.   ELSE
  2049.     WriteF('resultado: \d\n',fac(num))
  2050.   ENDIF
  2051. ENDPROC
  2052. PROC fac(n)
  2053.   DEF r
  2054.   IF FreeStack()<1000 OR CtrlC() THEN CleanUp(5) -> test extra
  2055.   IF n=1 THEN r:=1 ELSE r:=fac(n-1)*n
  2056. ENDPROC r
  2057. \endtt
  2058. por  supuesto,  es  dif\'{\i}cil que esta recursi\'on acabe con el espacio de la
  2059. pila,  y si lo hace, el programa se detiene con |FreStack()| tan r\'apido que
  2060. no  te  dar\'a  tiempo a pulsar |Ctrl-C|, pero aqu\'{\i} lo que cuenta es la idea.
  2061. Una definici\'on de |fac(n)| menos segura ser\'{\i}a:
  2062. \ejemplos
  2063. &|PROC fac(n) IS IF n=1 THEN 1 ELSE fac(n-1)*n|\cr
  2064. \proto{mem:=FastNew(tama\~no)}
  2065. \pproto{FastDispose(mem,tama\~no)}
  2066. \pproto{FastDisposeList(lista)}
  2067. |FastNew()| y |FastDispose()| substituyen a |NewR(size)| y |Dispose(ptr)| (|NEW|
  2068. y |END| los utilizan).  Esto es lo que tienen en com\'un:
  2069. \item{$-$} pueden lanzar excepciones |"NEW"|.
  2070. \item{$-$} la memoria siempre se inicializa a cero.
  2071. \item{$-$} liberaci\'on autom\'atica al final del programa.
  2072. \espacio
  2073. aunque deben se\~nalarse las siguientes diferencias positivas\nota{con objetos
  2074. |<=256| bytes, con mayores se usa |NewR()| y |Dispose()|} :
  2075. \item{$-$} son entre 10 y 50 veces m\'as r\'apidas (!)
  2076. \item{$-$} usan algo menos de memoria para objetos peque\~nos.
  2077. \item{$-$} no fragmentan la memoria.
  2078. \espacio
  2079. y negativas :
  2080. \item{$-$} no liberan la memoria, la reciclan.
  2081. \item{$-$} |FastDispose()| necesita tama\~no exacto de la reserva. |END| tambi\'en.
  2082. \espacio
  2083. Para liberar listas reservadas con |NEW| se necesita utilizar la funci\'on
  2084. |FastDisposeList()|.  Dado que las listas tienen longitud, no hace falta el
  2085. par\'ametro de tama\~no.
  2086. \seccion Matem\'aticas y otras.
  2087. \proto{a:=And(b,c)}
  2088. \pproto{a:=Or(b,c)}
  2089. \pproto{a:=Not(b)}
  2090. \pproto{a:=Eor(b,c)}
  2091. Estas  funcionan con  las  operaciones usuales,  tanto booleanas  como
  2092. aritm\'eticas.  Se\~nalar que existen operadores para |And()| y |Or()|.
  2093. \proto{a:=Mul(b,c)}
  2094. \pproto{a:=Div(a,b)}
  2095. Realizan  la  misma operaci\'on que los operadores |*| y |/|, aunque con
  2096. 32~bits  completos.   Por razones de velocidad, las operaciones normales
  2097. son |16bit*16bit=32bit| y |32bit/16bit=16bit|.  Suficiente para pr\'acticamente
  2098. todos los c\'alculos, y si no lo es, puedes usar |Mul()| y |Div()|\nota{en este
  2099. caso, |a| se divide entre |b|, y no |b| entre |a|.}.
  2100. \proto{bool:=Odd(x)}
  2101. \pproto{bool:=Even(x)}
  2102. \espacio
  2103. Retorna |TRUE| o |FALSE| si la expresi\'on es impar (|Odd()|) o par (|Even()|).
  2104. \proto{Min(a,b)}
  2105. \pproto{Max(a,b)}
  2106. Computan el m\'{\i}nimo y m\'aximo de dos enteros.
  2107. \proto{numaleat:=Rnd(max)}
  2108. \pproto{semilla:=RndQ(semilla)}
  2109. |Rnd()| computa  un n\'umero  aleatorio a partir  de una  semilla interna,
  2110. oscilando entre |0...max-1|.  Por ejemplo, |Rnd(1000)| retorna un entero entre
  2111. |0...999|.  Para inicializar la semilla interna, llama a  |Rnd()| con un valor
  2112. negativo; el |Abs()| de ese valor ser\'a la semilla inicial.
  2113. \noin |RndQ()|  computa  un n\'umero  aleatorio  m\'as  r\'apido que  |Rnd()|,  aunque
  2114. retorna n\'umeros en  todo el rango de los 32~bits.  Usa  el resultado como
  2115. semilla  para  la  siguiente  llamada,  y  como  semilla inicial  utiliza
  2116. cualquier valor grande, como |$A6F87EC1|.
  2117. \proto{valorabs:=Abs(valor)}
  2118. Computa el valor absoluto.
  2119. \proto{s:=Sign(v)}
  2120. Computa el signo de |v|, es decir, retorna |-1|, |0| o |1|.
  2121. \proto{a,b:=Mod(c,d)}
  2122. Divide  |c| (32bit)  entre |d|  (16bit)  y  retorna el  m\'odulo |a| (16bit) y
  2123. opcionalmente  el resultado  |b| (16bit)  de la  divisi\'on.  |Mod()| retornar\'a
  2124. resultados err\'oneos si se excede el l\'{\i}mite de los 16~bits.
  2125. \proto{x:=Shl(y,num)}
  2126. \pproto{x:=Shr(y,num)}
  2127. Desplaza |y| |num| bits a la izquierda o a la derecha (bits nuevos a 0).
  2128. \proto{a:=Long(dir)}
  2129. \pproto{a:=Int(dir)}
  2130. \pproto{a:=Char(dir)}
  2131. Mira en  una direcci\'on determinada  de la  memoria y retorna  el valor
  2132. encontrado.  Funcionan con valores  de~32, 16  y~8~bits respectivamente.
  2133. Se\~nalar  que el  compilador  {\bf no}  comprueba si  |dir|  es una  direcci\'on
  2134. v\'alida.  Estas funciones est\'an disponibles  para que se utilicen  s\'olo en
  2135. los  casos  en  los  que  la lectura  y  escritura  de  memoria  mediante
  2136. |PTR TO |\<type>  har\'{\i}a  el programa  m\'as complejo  o  menos eficiente.  Es
  2137. {\bf desaconsejable} el uso de estas funciones.
  2138. \proto{PutLong(dir,a)}
  2139. \pproto{PutInt(dir,a)}
  2140. \pproto{PutChar(dir,a)}
  2141. Escribe el valor |a| en memoria.  Mira |Long()|, |Int()| y |Char()|.
  2142. \proto{y:=Bounds(x,a,b)}
  2143. Asegura que |x| se encuentre entre |a| y |b|, y lo ajusta de forma acorde si
  2144. es necesario.  Equivale a:
  2145. \ejemplos
  2146. &|y:=IF x<a THEN a ELSE IF x>b THEN b ELSE x|\cr
  2147. \seccion Enlace de cadenas y listas.
  2148.    E  proporciona un  conjunto de  funciones\nota{estas funciones de cadenas/listas
  2149. no tienen nada que ver con las listas-E o las listas Celdas-Lisp} que
  2150. permite la  creaci\'on de
  2151. listas enlazadas con los tipos de datos |STRING| y |LIST|, o cadenas y listas
  2152. creadas con |String()| y |List()| respectivamente.  Como ya  debes saber, las
  2153. cadenas  y las  listas,  tipos de  datos complejos,  son  punteros a  sus
  2154. respectivos  datos, y  tienen campos  extra en  offsets negativos  de ese
  2155. puntero, que indican su longitud y longitud m\'axima actuales.  Los offsets
  2156. de los campos son privados (|PRIVATE|).  Todos los tipos de datos complejos
  2157. tienen, adem\'as de esos dos,  un campo |next| (siguiente),  inicializado a
  2158. |NIL| por  omisi\'on,  y que se  puede usar para  construir listas  o cadenas
  2159. enlazadas, por  ejemplo.  Desde  ahora, usar\'e |complejo| para  denotar un
  2160. puntero a |STRING| o |LIST|,  y |cola| para denotar otro puntero de ese tipo,
  2161. o que ya tenga otras cadenas enlazadas a \'el.  |cola| tambi\'en puede ser un
  2162. puntero |NIL|, indicando el final de una lista enlazada. Se pueden usar
  2163. las siguiente funciones:
  2164. \proto{complejo:=Link(complejo,cola)}
  2165. Pone |cola| en el |next| de |complejo|.  Retorna |complejo| de nuevo.
  2166. \Ejemplos
  2167. Ejemplo:&|DEF s[10]:STRING, t[10]:STRING|\cr
  2168.         &|Link(s,t)|\cr
  2169.         &crear\'a una lista enlazada como: \quad |s --> t --> NIL|\cr
  2170. \proto{cola:=Next(complejo)}
  2171. Lee el campo |next| de |complejo|.  Puede ser |NIL|, o una lista enlzada
  2172. completa.  |Next(NIL)| resultar\'a en  |NIL|,  luego es seguro llamar a  |Next()|
  2173. cuando no est\'as seguro si estas al final de la lista enlazada o no.
  2174. \proto{cola:=Forward(complejo,num)}
  2175. Como |Next()|,  s\'olo que adelanta |num| enlaces en lugar de uno,  es
  2176. decir |Forward(c,1)| equivale a |Next(c)|.  Puedes utilizar |Forward()| con un
  2177. |num| grande de forma segura, |Forward()| se detendr\'a si encuentra |NIL|
  2178. mientras recorre los enlaces, y retornar\'a |NIL| en ese caso.
  2179. \proto{DisposeLink(complejo)}
  2180. Como |Dispose()|, con dos diferencias:  s\'olo sirve para cadenas y listas
  2181. reservadas con |String()| o |List()|,  adem\'as liberar\'a el resto de |complejo|
  2182. autom\'aticamente.  Se\~nalar tambi\'en  que se puede usar con listas enlazadas
  2183. grandes  que contengan tanto cadenas reservadas con |String()| como algunas
  2184. reservadas localmente o globalmente con |STRING|.
  2185. \espacio
  2186. Puede que te interese mirar\enspace |Src/Utils/D.e|\enspace  para ver un  buen
  2187. ejemplo  de como se  puede hacer buen uso de listas o cadenas enlazadas
  2188. en programas reales.
  2189. \seccion Celdas-Lisp y funciones de celdas.
  2190. Vaya. Correcto. Pensabas que el LISP era divertido, entonces prueba E.\nota{o la
  2191. historia de por qu\'e E es un LISP mejor que el propio LISP |:-)|}
  2192. \espacio
  2193.    A  partir de  la versi\'on  v3,  E  tiene el  tipo de datos celda,  casi
  2194. id\'entico a las celdas del lenguaje LISP\null{}.  M\'as t\'ecnicamente, E~tiene\nota{
  2195. ``Celdas-Lisp con recogida de residuos con marcas conservadoras e intercambio''}:
  2196. \ejemplos
  2197. &``Conservative Mark and Sweep Garbage-Collected Lisp-Cells''\cr
  2198. \espacio
  2199. B\'asicamente,  implica el ser capaz de reservar celdas-LISP, las cuales
  2200. son pares de valores:
  2201. \ejemplos
  2202. &|x:=<a|\|{}|b>|\cr
  2203. \finsma
  2204. Lo  cual  se  parece mucho a |NEW [a,b]:LONG|, s\'olo que ahora~E liberar\'a
  2205. los  8~bytes  en  cuesti\'on  por s\'{\i} s\'olo cuando se encuentre que necesita
  2206. memoria,  y  no  haya  punteros apuntando a la celda.  En la pr\'actica esto
  2207. significa  que  puedes  tener  funciones  que crean celdas temporales sin
  2208. preocuparse  de liberarlas.  Y, cualquier\nota{este texto no explica
  2209. detenidamente como aprovechar las celdas por completo, ya que se han escrito
  2210. docenas de libros a ese respecto.} programador de LISP ser\'{\i}a capaz
  2211. de explicarte que con celdas puedes construir cualquier tipo de estrutura
  2212. de datos (m\'as notablemente \'arboles y listas).
  2213. \espacio
  2214. La selecci\'on de los valores se puede realizar usando  |Car(x)| y |Cdr(x)|,
  2215. dos funciones  de  LISP  que  seleccionan  los elementos  cabeza  y  cola
  2216. (primero, segundo) de la celda.  Si |x| es un |PTR TO LONG|, incluso se puede
  2217. utilizar |x[0]| y |x[1]|.
  2218. \espacio
  2219. Tambi\'en se pueden escribir listas de celdas (atento a las comas):
  2220. |<a,b,c>| \qquad  como abreviatura de \qquad |<a|\|{}|<b|\|{}|<c|\|{}|NIL>>>|
  2221. \espacio
  2222. La unificaci\'on de E sirve de alternativa a la selecci\'on |Car()| y |Cdr()|:
  2223. \ejemplos
  2224. & |x <=> <a,b|\|{}|c>|\cr
  2225. & |a+b+c|\cr
  2226. en vez de:
  2227. \ejemplos
  2228. &|Car(x)+Car(Cdr(x))+Cdr(Cdr(x))|\cr
  2229. \finsma
  2230. La unificaci\'on de celdas-LISP se parece a la unificaci\'on con listas-E.
  2231. Por ejemplo :
  2232. \ejemplos
  2233. &|x <=> <1,2|\|{}|a>|\cr
  2234. equivale a:
  2235. \ejemplos
  2236. &|IF Car(x)=1|\cr
  2237. &|  IF Car(Cdr(x))=2|\cr
  2238. &|    a:=Cdr(Cdr(x))|\cr
  2239. &|    ...|\cr
  2240. \finsma
  2241. Tambi\'en existe el valor nil de LISP (|<>|), que equivale a |NIL| y |0|.
  2242. \espacio
  2243.    Veamos  algunas funciones  disponibles (se\~nalar  que |Cons()| {\bf solo} se
  2244. puede usar por medio de |<...>|)
  2245. \proto{h:=Car(c)}
  2246. \pproto{t:=Cdr(c)}
  2247. Fija el valor de la cabeza y la cola de la celda |c|.
  2248. \proto{bool:=Cell(c)}
  2249. Indica si |c| apunta a una celda, de forma que |Cell(<1>)=TRUE|,
  2250. y |Cell(3.14)=FALSE|\null{}.  No es una funci\'on r\'apida.
  2251. \proto{n:=FreeCells()}
  2252.    Determina  el n\'umero  de celdas libres disponibles.  Es muy lenta.  No
  2253. hay necesidad alguna de llamar a esta funci\'on, si no es por curiosidad.
  2254. \proto{SetChunkSize(k)}
  2255. Fija el tama\~no  de los bloques reservados para celdas  en |k|~kilobytes.
  2256. Por omisi\'on es 128k. Esta funci\'on s\'olo  se puede llamar una  vez, y s\'olo
  2257. antes de que tenga lugar la primera reserva constante (|<..>|). A partir de
  2258. ese momento esta funci\'on no tiene ning\'un efecto.
  2259. \espacio
  2260.    Resumiendo, hazte con  un buen libro sobre LISP para  entender bien la
  2261. programaci\'on con celdas.
  2262. \espacio
  2263.    Se pueden escribir funciones de LISP en E, con exactamente la misma
  2264. funcionalidad:
  2265. \ejemplos
  2266. &|PROC append(x,y) IS IF x THEN <Car(x)||append(Cdr(x),y)> ELSE y|\cr
  2267. &|PROC nrev(x) IS IF x THEN append(nrev(Cdr(x)),<Car(x)>) ELSE NIL|\cr
  2268. &|PROC sum(x) IS IF x THEN Car(x)+sum(Cdr(x)) ELSE 0|\cr
  2269. \finsma
  2270. Tambi\'en se permite el uso de implementaci\'on destructiva para funciones
  2271. como estas.
  2272. \Espacio
  2273. \subsec Notas t\'ecnicas.
  2274. El recolector de residuos (RR) de E implementa un algoritmo de marca e
  2275. intercambio conservativo que se ha comprobado  que es entre~5 y~25 veces m\'as
  2276. r\'apido  que  las distintas  implementaciones  l\'ogicas  y funcionales  del
  2277. Amiga. Conservativo  significa que en  caso de duda,  el~RR no  libera la
  2278. celda. Esto es necesario debido a que en un lenguaje sin tipos como el~E,
  2279. el~RR podr\'{\i}a  llegar facilmente a un  valor que no es  un puntero v\'alido,
  2280. \noin El RR reserva bloques grandes (por omisi\'on 128k), en los cuales guarda
  2281. las celdas. Si se acaban  las celdas, recolectar\'a los residuos analizando
  2282. la pila  y los registros en  busca de punteros  al \'area de celdas,  y los
  2283. marcar\'a de forma recursiva. Tras eso,  todas las celdas que no hayan sido
  2284. marcadas se volver\'an a utilizar, y si la ganancia tras la recolecci\'on fue
  2285. peque\~na, se  reservar\'a un  nuevo bloque  (si eso  falla se  alcanzar\'a una
  2286. excepci\'on |"NEW"|).
  2287. \subsec Interacci\'on con otros valores de E.
  2288. \item{$-$} No representa ning\'un problema almacenar otros valores en las celdas.  Se pueden
  2289. poner objetos, cadenas, reales, cualquier cosa en celdas  sin confundir
  2290. demasiado al~RR.
  2291. \item{$-$} S\'{\i} es problem\'atico el almacenar celdas en otros valores, por ejemplo un
  2292.   puntero a una celda en un objeto din\'amico,  ya que  el~RR no ser\'a capaz
  2293.   de encontrarlo all\'{\i}.  Sin embargo, pienso  que ese caso aparecer\'a raras
  2294.   veces.  Los punteros  a celdas  se pueden  guardar de  forma segura  en
  2295.   variables  globales  o  locales,  incluso  registros,  y  en  cualquier
  2296.   estructura de datos de la pila. (!`y m\'as importante, en otras celdas!)
  2297. \subsec Intr\'{\i}nsecos.
  2298. \item{$-$} El RR no puede, de momento, recolectar celdas cuya lista-Car  tenga una
  2299.   longitud |>1000| o similar, por ejemplo |<<<NIL:a>:b>:c>|,  pero  con  1000
  2300.   entradas en vez de~3.  Esto es muy dif\'{\i}cil que ocurra ya que las listas
  2301.   de este tipo se suelen formar con \hbox{listas-Cdr}, que el~RR puede controlar
  2302.   hasta de tama\~no infinito. (alcanzar\'a una |"STCK"| si eso falla).
  2303. \item{$-$} El c\'odigo ensamblador en l\'{\i}nea  no debe poner cosas  en la pila  que no
  2304.   est\'en alineadas a 32~bits.  Esto ya era necesario en v2.1b,  pero ahora
  2305.   es m\'as imprescindible.
  2306. \subsec Resumiendo.
  2307. Hay una relaci\'on entre velocidad y espacio  con respecto al  tama\~no de
  2308. los bloques.  La reserva de bloques peque\~nos es, obviamente,  interesante
  2309. ya que no desperdicia memoria,  sin embargo,  al recolectar residuos,  el
  2310. trabajo de control de los punteros es proporcional al n\'umero de espacios.
  2311. Por tanto:
  2312. \item{$-$} Si  es m\'as importante la velocidad,  ajusta el tama\~no de los bloques de
  2313.   forma que s\'olo se necesite un bloque.  Si  el uso m\'aximo de memoria  de
  2314.   celdas en cualquier momento es de~50k, un espacio de bloque de~100k~o
  2315.   150k ofrecer\'a un rendimiento \'optimo.
  2316. \item{$-$} Si lo m\'as importante es la memoria, en el ejemplo anterior un tama\~no de
  2317.   bloque de~20k~o  30k ser\'a  bastante \'optimo en cuanto a uso de memoria.
  2318.   En resumen,  temporiza  el uso  del algoritmo de celdas  en situaciones
  2319.   complicadas para ver la relaci\'on velocidad\b/memoria m\'as apropiada.
  2320. \endchapter\saltacap
  2321. \beginchapter Cap\'{\i}tulo 10. Funciones\\de biblioteca\\y m\'odulos
  2322. Como habr\'as notado en secciones anteriores el fragmento de c\'odigo enlazado
  2323. de forma  autom\'atica antes  de tu  c\'odigo, llamado  {\sl c\'odigo de
  2324. inicializaci\'on}, siempre abre las tres librer\'{\i}as\nota{N.T.: a lo que me refiero
  2325. con librer\'{\i}a es en realidad una {\it biblioteca}, es decir,  una biblioteca
  2326. o colecci\'on de funciones.  Lo que pasa es  que debido a  que en ingl\'es se les
  2327. llaman libraries  (como debe ser),  parace ser que a uno se le pega m\'as r\'apido
  2328. lo de librer\'{\i}a~\dots\enspace|:-(|} |intuition|, |dos| y |graphics|
  2329. (y algunas  veces |mathieeesigbas|), y  debido a esto, el  compilador tiene
  2330. todas las llamadas a estas  cuatro librer\'{\i}as (incluyendo |exec|) integradas
  2331. en el compilador (hay unos cientos  de ellas).  Estas son  hasta la versi\'on~3.00~(v39)
  2332. de AmigaDos.  Para llamar al |Open()| de `dos' s\'olo tienes que escribir:
  2333. \ejemplos
  2334. &|handle:=Open('mifichero',OLDFILE)|\cr
  2335. o para |AddDisplayInfo()| de la librer\'{\i}a |graphics|:
  2336. \ejemplos
  2337. &|AddDisplayInfo(midispinfo)|\cr
  2338. \finsma
  2339. Es tan sencillo como eso.
  2340. \seccion Interface con el sistema Amiga con los m\'odulos de v39.
  2341. Para usar cualquier  otra librer\'{\i}a, a parte de las cinco de la secci\'on
  2342. anterior, debes  recurrir a  los m\'odulos.  Igualmente si  deseas utilizar
  2343. alg\'una definici\'on de  |OBJECT|o o |CONST| de los includes  del Amiga, como es
  2344. normal en~C o ensamblador, tambi\'en necesitar\'as los  m\'odulos.  Los m\'odulos
  2345. son  ficheros binarios  que  pueden incluir  definiciones de  constantes,
  2346. objetos librer\'{\i}as  y funciones  (c\'odigo).  El hecho de que  sean binarios
  2347. tiene la ventaja sobre  el \ASCII/ (como en~C y en  ensamblador), que no es
  2348. necesario  compilarlos  una y  otra  vez,  cada  vez  que se  compila  un
  2349. programa.   La desventaja es que no se puede leer con tanta facilidad, se
  2350. necesita una utilidad como |ShowModule| para ver su contenido.  Los m\'odulos
  2351. que contienen las definiciones de librer\'{\i}as  se encuentran en el directorio
  2352. raiz  de |EMODULES:|  (el directorio |modules/| en la distribuci\'on), las
  2353. definiciones   de   constantes\b/objetos   est\'an   en  los  subdirectorios,
  2354. estructurados de la misma forma que los originales de Commodore.
  2355. \Espacio
  2356. \ejemplos
  2357. \qquad Sintaxis:&|MODULE |\<nombrem\'odulo>|, ...|\cr
  2358. \finsma
  2359. Lee un m\'odulo.  Un m\'odulo es un fichero binario  con informaci\'on sobre
  2360. librer\'{\i}as,  constantes,  y a veces, funciones.  El uso de m\'odulos permite
  2361. usar librer\'{\i}as y funciones que eran desconocidas por el compilador.
  2362. \espacio
  2363.    Veamos  un  ejemplo,  una  versi\'on   reducida  del  ejemplo
  2364. |source|\b/|Examples|\b/|asldemo.e|,  que usa m\'odulos para obtener  un requester de
  2365. ficheros de la |Asl.library|~2.0.
  2366. \begintt
  2367. MODULE 'Asl', 'libraries/Asl'
  2368. PROC main()
  2369.   DEF req:PTR TO filerequester
  2370.   IF aslbase:=OpenLibrary('asl.library',37)
  2371.     IF req:=AllocFileRequest()
  2372.       IF RequestFile(req)
  2373.         WriteF('Fichero: "\s" in "\s"\n',req.file,req.drawer)
  2374.       ENDIF
  2375.       FreeFileRequest(req)
  2376.     ENDIF
  2377.     CloseLibrary(aslbase)
  2378.   ENDIF
  2379. ENDPROC
  2380. \endtt
  2381. el  compilador obtiene del m\'odulo |'asl'| las definiciones de funciones
  2382. de  |asl|  como  |RequestFile()|,  y  la  variable  global  |aslbase|, que s\'olo
  2383. necesita que el programador la inicialize.  De |'libraries/Asl'| obtiene la
  2384. definici\'on  del  objeto  |'filerequester'|,  el  cual  se  usa para leer el
  2385. fichero que seleccion\'o el ususario.
  2386. \espacio
  2387. Bueno, ?`Pensabas que era m\'as dif\'{\i}cil tener un requester de ficheros en~E?
  2388. \seccion Compilando m\'odulos propios.
  2389. A partir  de la  versi\'on v3  puedes agrupar en un solo fuente todos los  |PROC|s, |CONST|s,
  2390. |OBJECT|os  y, hasta  cierto punto tambi\'en  las variables  globales, que  te
  2391. parezca esten  relacionados entre s\'{\i} de  alguna forma. Utiliza |OPT MODULE| para
  2392. indicar  al compilador~EC que ese  fichero se
  2393. supone que es un m\'odulo, y luego comp\'{\i}lalo a  un fichero |.m| que se podr\'a usar en
  2394. el programa principal, igual que con los dem\'as m\'odulos.
  2395. \espacio
  2396. Por omisi\'on todos los elementos de un m\'odulo son |PRIVATE|, es decir, no
  2397. son accesibles al c\'odigo que importa el fichero |.m|.  Para hacer  visibles
  2398. los elementos que quieras, simplemente escribe |EXPORT| antes de ellos:
  2399. \begintt
  2400. EXPORT ENUM TESTING,ONE,TWO,THREE,FOUR
  2401. EXPORT DEF var_global_importante, bla:PTR TO x
  2402. EXPORT OBJECT x
  2403.   sig, indice, termino
  2404. ENDOBJECT
  2405. EXPORT PROC burp()
  2406.  /* lo que sea */
  2407. ENDPROC
  2408. \endtt
  2409. |EXPORT| es \'util para hacer la distinci\'on entre privado y p\'ublico,
  2410. especialmente, cuando se puede acceder a todas las funciones de un objeto
  2411. mediante  |PROC|s, puedes desear mantener un |OBJECT|o privado como una forma
  2412. efectiva de {\sl ocultamiento de datos}. |EXPORT| puede aparecer en cualquier
  2413. l\'{\i}nea, en cuyo caso no afectar\'a a nada.
  2414. \noin Si  es necesario  exportar {\sl todos}  los  elementos de  un m\'odulo  (por
  2415. ejemplo,  uno  que  s\'olo  tenga constantes), con |OPT EXPORT| se exportr\'a
  2416. todo, sin que haga falta utilizar |EXPORT|s individuales.
  2417. \noin Las variables globales necesitan una atenci\'on especial:
  2418. \item{$-$} Intenta  eludir  muchas variables globales.  El tener muchas  variables
  2419.   globales en los m\'odulos hace los proyectos propensos a errores.
  2420. \item{$-$} Las variables globales  de  un m\'odulo  no pueden tener inicializaciones
  2421.   directas en la sentencia |DEF| (la raz\'on de esto se aclar\'a m\'as tarde). Por ejemplo:
  2422. \itemitem{} |DEF a         |\qquad y no\qquad |DEF a=1|
  2423. \itemitem{} |DEF a:PTR TO x|\qquad y no\qquad |DEF a[10]:ARRAY OF x|
  2424. \item{$-$} Las variable globales  de  un m\'odulo  que  no  se exportan  operan como
  2425.   locales  al m\'odulo,  es decir,  nunca  chocar\'an  con globales  de otros
  2426.   m\'odulos.   Aquellas exportadas, se combinan con las dem\'as, es decir, si
  2427.   se usa una variable con el mismo nombre, tanto en el programa principal
  2428.   como  en  m\'odulos, \'esta ser\'a una s\'ola y la misma para los dos.  Este es
  2429.   el motivo  de que se pueda escribir |DEF a[10]:ARRAY OF x| en el programa
  2430.   principal,  y |EXPORT DEF a:PTR TO x| en  el m\'odulo,  para  compartir  el
  2431.   arreglo.  Adem\'as, si ambos usan, por ejemplo, |gadtools.m|, s\'olo uno de
  2432.   los  dos  tiene  que  inicializar  |gadtoolsbase| para que ambos puedan
  2433.   hacer llamadas a la librer\'{\i}a.  Si no quieres compartir las bases de las
  2434.   librer\'{\i}as (es decir, quieres tener una base de librer\'{\i}a local,privada),
  2435.   simplemente redecl\'arala en un  |DEF|  de un m\'odulo que no la |EXPORT|e.  Si
  2436.   exportas una variable en un m\'odulo de proprosito general,  aseg\'urate de
  2437.   que tenga un nombre \'unico.
  2438. \item{$-$} El uso  de variables  en  m\'odulos  que proporcionan  tipos de  datos de
  2439.   prop\'osito general necesita  de una atenci\'on especial, ya  que el m\'odulo
  2440.   puede ser  usado desde  m\'as de un  m\'odulo, en cuyo  caso no  est\'a claro
  2441.   quien es el responsable de los recursos.  Ten esto bien en cuenta.
  2442. \Espacio
  2443. \subsec Uso de m\'odulos dentro de m\'odulos.
  2444. Esto requiere una atenci\'on extra. Si  el m\'odulo (B) que incluyes en tu
  2445. propio m\'odulo  (A) es uno  que s\'olo  declara |CONST|s, |LIBRARY|s  y |OBJECT|os
  2446. (sin c\'odigo)  no sucede nada especial,  sin embargo, si B  incluye |PROC|s,
  2447. entonces es obvio  que ese c\'odigo necesita ser enlazado  m\'as tarde con el
  2448. programa principal cuando se enlace A\null{}. Por ello, si un programa principal
  2449. usa A,  B debe estar presente en la compilaci\'on.  El hecho de que A necesite
  2450. a  B se guarda en A, y se puede ver con |ShowModule|.  Esta cadena de
  2451. usos  puede  crecer  creando  un  \'arbol  de  dependencias, que tiene como
  2452. resultado que aunque s\'olo utilices un m\'odulo en tu programa, se enlazar\'an
  2453. a  \'el  de  forma  autom\'atica  unos  cuantos m\'as.  Por ello, el sistema de
  2454. m\'odulos  de~E mantiene de forma autom\'atica las dependencias para las que
  2455. otros  lenguajes  necesitan  makefiles.   |EC|~tambi\'en permite dependencias
  2456. circulares, y lee/enlaza un m\'odulo a lo sumo una vez (es decir, no enlaza
  2457. m\'odulos  que  no  se usaron).  Una cosa que el sistema de m\'odulos de E no
  2458. realiza  de  forma  autom\'atica  es  recompilar  m\'odulos dependientes.  Si
  2459. cambias  B,  a  menudo  ser\'a necesario recompilar A tambi\'en, ya que puede
  2460. hacer  referencia  de  offsets, etc, de la versi\'on antigua de B, lo cual
  2461. puede provocar que el c\'odigo rompa.  Si esto se empieza a complicar en tu
  2462. proyecto, puedes usar una utilidad como |E-Build|.
  2463. \noin Prueba el nuevo |ShowModule| para ver lo que pone |EC| en los m\'odulos.
  2464. \Espacio
  2465. \subsec Inclusi\'on de m\'odulos de otros directorios.
  2466. Por  omisi\'on, al nombre del m\'odulo se le pone como prefijo |EMODULES:|
  2467. para  obtener  el  fichero en concreto.  Ahora puedes anteponer un |*| al
  2468. m\'odulo  para indicar el directorio en el que encuentra el c\'odigo fuente, de
  2469. forma que si en el fuente |WORK:E/burp.e| apareciese:
  2470. \ejemplos
  2471. &|MODULE 'bla', '*bla'|\cr
  2472. el compilador buscar\'{\i}a los m\'odulos |EModules:bla.m| y |WORK:E/bla.m|.
  2473. \espacio
  2474.    Esta  es,  naturalmente,  la  forma   de  incluir  componentes  de  tu
  2475. aplicaci\'on en otras partes.  Si  escribes m\'odulos  que usas en  muchos de
  2476. tus  programas,  ser\'{\i}a  bastante  conveniente  guardarlos  dentro  de  la
  2477. jerarqu\'{\i}a de |EModules:|,  y el lugar adecuado para esto es el directorio
  2478. |EModules:other/|.
  2479. \seccion El cach\'e de m\'odulos.
  2480. {\it (Se trata en detalle en la seccion sobre |ShowCache/FlushCache|).}
  2481. \endchapter\saltacap
  2482. \beginchapter Cap\'{\i}tulo 11. Expresiones\\entrecomilladas
  2483. Las expresiones entrecomilladas empiezan  con una comilla inversa ``|`|''.
  2484. Su  valor  {\bf no}  es el resultado de la computaci\'on de la expresi\'on, sino la
  2485. direcci\'on  del  c\'odigo  que la computa.  Este resultado se puede utilizar
  2486. como una variable, o como argumento de ciertas funciones. Por ejemplo,
  2487. \ejemplos
  2488. &|mifunc:=`x*x*x|\cr
  2489. hace que ahora |mifunc| sea un puntero a una {\it funci\'on} que  computa |x^3|  cuando se
  2490. eval\'ua.  Estos punteros a funciones  son bastante diferentes de  los |PROC|s
  2491. normales, y nunca  se deben mezclar o confundir.  La principal diferencia
  2492. de las expresiones entrecomilladas es que s\'olo son expresiones simples, y
  2493. por  tanto no  pueden tener  sus  propias variables locales.  En  nuestro
  2494. ejemplo, |x| es o una variable global o una variable local.  Ah\'{\i} es donde
  2495. debemos tener  precauci\'on:  si evaluamos |mifunc| en alg\'un otro lugar del
  2496. mismo |PROC|, |x| puede ser local,  pero si |mifunc| se pasa como par\'ametro a
  2497. otro  |PROC|, y luego se eval\'ua, entonces |x| debe ser global.  El compilador
  2498. no realiza esta comprobaci\'on por t\'{\i}.
  2499. \proto{Eval(func)}
  2500. Simplemente eval\'ua la expresi\'on entrecomillada (|exp = Eval(`exp)|).
  2501. Debido a que  E  es, de alguna  forma,  un  lenguaje sin tipos,  el
  2502. escribir |Eval(x*x)| de forma accidental  en lugar de |Eval(`x*x)| pasar\'a
  2503. desapercibido al compilador,  y propiciar\'a muchos problemas  en tiempo de
  2504. ejecuci\'on: el valor del |x*x| se usar\'a como un puntero a c\'odigo.
  2505. \espacio
  2506. Para entender el  motivo por el que  las expresiones entrecomilladas
  2507. representan una caracter\'{\i}stica importante piensa en los siguientes casos:
  2508. si  quisieras  realizar  una  serie  de acciones en un grupo de variables
  2509. diferentes,  normalmente  escribir\'{\i}as  una  funci\'on  y  la  llamar\'{\i}as con
  2510. diferentes  argumentos.  Pero, ?`qu\'e ocurre cuando el elemento que quieres
  2511. dar como argumento es un fragmento de c\'odigo?  En lenguajes tradicionales
  2512. esto  no  ser\'{\i}a  posible, por lo que necesitar\'{\i}as 'copiar' los bloques de
  2513. c\'odigo  que  representan la funci\'on, y poner la expresi\'on en ellos.  En~E
  2514. no.   Digamos  que  quieres  escribir  un  programa que mida el tiempo de
  2515. ejecuci\'on de diferentes expresiones.  En~E simplemente escribir\'{\i}as:
  2516. \begintt
  2517. PROC mide(func,titulo)
  2518.   -> realizar todo tipo de inicializaciones del tiempo
  2519.   Eval(func)
  2520.   -> y el resto
  2521.   WriteF('\s tardo \d en ejecutarse\n',titulo,t)
  2522. ENDPROC
  2523. \endtt
  2524. y luego lo llamas con:
  2525. \ejemplos
  2526. &|mide(`x*x*x,'multiplicacion')|\cr
  2527. &|mide(`calcenorme(),'calculo grande')|\cr
  2528. \finsma
  2529. En cualquier otro lenguaje imperativo, necesitar\'{\i}as escribir copias de
  2530. |mide()|  para  cada  llamada,  o  poner  cada  expresi\'on  en  una  funci\'on
  2531. diferente.  Este es un ejemplo sencillo,  piensa en lo que  podr\'{\i}as hacer
  2532. con estructuras de datos (|LIST|as) y c\'odigo sin evaluar:
  2533. \ejemplos
  2534. &|funcsdibu:=[`Plot(x,y,c),`Line(x,y,x+10,y+10,c),`Box(x,y,x+20,y+20,c)]|\cr
  2535. \finsma
  2536. La idea de usar funciones como variables normales\b/valores no
  2537. es  nuevo de~E, las  expresiones entrecomilladas  vienen del
  2538. LISP, que adem\'as  tambi\'en tiene las llamadas funciones {\sl Lambda},  de alguna
  2539. forma  m\'as  potentes, y  que  tambi\'en  se  pueden  dar como  argumentos  a
  2540. funciones.  Las  expresiones entrecomilladas  de~E  se pueden  ver  como
  2541. {\sl lambdas} sin par\'ametros (o s\'olo de par\'ametro global).
  2542. \seccion Funciones predefinidas.
  2543. \proto{MapList(dirvar,lista,listavar,func)}
  2544. Aplica una  funci\'on a todos  los elementos de  la lista y  retorna los
  2545. resultados en |listavar|.  |func| debe ser una  expresi\'on entrecomillada,
  2546. y |var| (que tomar\'a todos los valores de la lista) se dar\'a por referencia.
  2547. Retorna |listavar|.
  2548. \Ejemplos
  2549. Ejemplo:& |MapList({x},[1,2,3,4,5],r,`x*x)   resulta con r: [1,4,9,16,25]|\cr
  2550. \proto{ForAll(dirvar,lista,func)}
  2551. Retorna |TRUE| si la funci\'on (expresi\'on entrecomillada) se eval\'ua a |TRUE|
  2552. para todos los  elementos de la lista,  y |FALSE| en otro caso.  Tambi\'en se
  2553. usa para aplicar una cierta funci\'on a todos los elementos de la lista:
  2554. \ejemplos
  2555. |ForAll({x},['uno','dos','tres'],`WriteF('ejemplo: \s\n',x))|\cr
  2556. \proto{Exists(dirvar,lista,func)}
  2557. Como  |ForAll()|,  s\'olo  que \'esta retorna |TRUE| si para alg\'un elemento la
  2558. funci\'on se  eval\'ua a  |TRUE|  (|<>0|).  |ForAll()|  siempre  eval\'ua  todos  los
  2559. elementos, pero |Exists()| probablemente no.
  2560. \proto{SelectList(v,lista,listavar,exprentrecom)}
  2561. Muy parecida a |MapList()|,  s\'olo  que ahora  no guarda el  resultado de
  2562. |exprentrecom|, lo  usa como valor booleano,  y s\'olo los valores para los
  2563. cuales es cierta se guardan en |listavar|  ---que  debe  poder  guardar el
  2564. mismo n\'umero de elementos que |lista|.  Retorna la longitud de |listavar|.
  2565. \Ejemplos
  2566. Ejemplo:&|SelectList({x},[1,2,0,3,NIl],r,`x<>0)  resulta con r=[1,2,3]|\cr
  2567. \finsma
  2568. Ejemplo pr\'actico de utilizaci\'on:
  2569. \noin Reservamos diferentes tama\~nos de memoria en una sentencia, los comprobamos
  2570. a la vez,  y  los liberamos todos de una vez,  pero s\'olo  los que se
  2571. pudieron reservar.  (Este ejemplo necesita v37+)
  2572. \begintt
  2573. PROC main()
  2574.   DEF mem[4]:LIST,x
  2575.   MapList({x},[200,80,10,2500],mem,`AllocVec(x,0))       -> reservamos
  2576.   WriteF(IF ForAll({x},mem,`x) THEN '!`Si!\n' ELSE '!`No!\n') -> ?`exito?
  2577.   ForAll({x},mem,`IF x THEN FreeVec(x) ELSE NIL)  -> solo libera <>NIL
  2578. ENDPROC
  2579. \endtt
  2580. F\'{\i}jate en  la ausencia de  iteraci\'on en este c\'odigo.  Intenta escribir
  2581. este ejemplo en cualquier otro lenguaje para ver porqu\'e es especial.
  2582. \endchapter\saltacap
  2583. \beginchapter Cap\'{\i}tulo 12. Los n\'umeros\\Reales
  2584. Los n\'umeros reales en E (o FLOATs, como quieras)  son bastante  diferentes de
  2585. los de otros lenguajes.  Esto es debido, sobre todo, al hecho de que~E realmente no
  2586. discrimina entre tipos de valores.  Te aviso que debes
  2587. entender {\bf bien} esta secci\'on antes de intentar usar reales.
  2588. \Espacio
  2589. En  E un real no es m\'as que otro valor de 32 bits.  El compilador de~E
  2590. los trata como si fueran enteros o punteros,  con la diferencia de que su
  2591. representaci\'on  interna  significa algo totalmente diferente.  El formato
  2592. de los reales en~E es el estandard |IEEEsingle|.
  2593. \noin Un valor real es similar a un  entero, con la salvedad de que tiene un
  2594. punto en alg\'un lugar.  Por ejemplo, los siguientes son reales v\'alidos:
  2595. \ejemplos
  2596. &$3.14159\qquad .1\qquad 1.\qquad -12345.6$\cr
  2597. y estos no lo son:
  2598. \ejemplos
  2599. &$.\qquad 1234$\cr
  2600. (es decir, debe tener al menos un |.| y un caracter |0-9|).
  2601. \espacio
  2602. Puedes usar estos valores en pr\'acticamente todos lo lugares en los que
  2603. es legal un valor |LONG|,  es decir, si tienes una  funci\'on o estructura de
  2604. datos que utiliza valores |LONG| cualesquiera, tambi\'en utilizar\'a reales.
  2605. \begintt
  2606. DEF f=3.14
  2607. myobj.x:=.1
  2608. fun(f,2.73)
  2609. \endtt
  2610. \seccion Computaci\'on con reales.
  2611. Debido a que los reales son como |LONG|s para E, \'este utilizar\'a con toda
  2612. seguridad  la aritm\'etica  de  enteros con  ellos cuando  se  usan en  una
  2613. expresi\'on,  lo cual  seguramente no  es lo  que quieres.  Adem\'as, tambi\'en
  2614. ser\'{\i}a interesante poder  convertir de enteros a reales y viceversa.  Con
  2615. el operador ``|!|'' se puede hacer todo esto.
  2616. \espacio
  2617. Supongamos  que  en los siguientes  ejemplos  |a|,|b|,|c|  contienen valores
  2618. enteros, y que |x|,|y|,|z| contienen valores reales.
  2619. \espacio
  2620. Por omisi\'on, una expresi\'on en E se considera una expresi\'on entera.  Lo
  2621. que hace |!| cuando apararece en una expresi\'on es:
  2622. \item{$-$} Cambia la expresi\'on de  entero  a real.  Cualquier operador que le siga
  2623.   (|+ * - / = <> > < >= <=|)  realizar\'a  operaciones  con reales.  |!| puede
  2624.   aparecer tantas veces como quieras.
  2625. \item{$-$} La expresi\'on que aparece antes de |!|,  si hubo alguna, se convierte al
  2626.   tipo apropiado.
  2627. \espacio
  2628. Ejemplos:
  2629. \begintt
  2630. x:=a!       -> convierte "a" en real, y pone el resultado en x. "a" es
  2631.             -> una expresion entera,  que se cambia por real,  lo cual
  2632.             -> implica una conversion.
  2633. a:=!x!      -> convierte "x" a entero y guarda el resultado en "a".
  2634. x:=y        -> aqui no se necesita "!" ya que no es necesario ningun
  2635. x:=Ftan(y)  -> operador matematico ni conversion.
  2636. x:=!y*z     -> "*" actua sobre 'y' y 'z' como reales porque "!" denota
  2637.             -> el todo como expresion real.  El resultado real va a x.
  2638. a:=b!*x+y!  -> un ejemplo mas complejo:  el entero 'b' se convierte en
  2639.             -> real, luego se multiplica por 'x' (como reales) y se le
  2640.             -> suma 'y' (como reales).  El resultado  se  convierte en
  2641.             -> entero y se pone en el entero 'a'".
  2642. \endtt
  2643. \begintt
  2644. x:=!y*z-z*y+(a!)+z/z  -> los operadores (+*-/) se computan como reales,
  2645. z:=!x*Fsin(!x*y)      -> y el entero 'a'  se convierte a real en algun
  2646.                       -> lugar de la expresion. Como ( y ) denotan una
  2647.                       -> nueva expresion, tiene su propio estado de !.
  2648.                       -> La misma idea para la segunda funcion.
  2649. IF !x<0.1 THEN WriteF('!`Valor real demasiado bajo!\n')
  2650. -> Como ves "!" tambien sirve para los seis operadores de comparacion.
  2651. \endtt
  2652. \seccion Funciones de reales predefinidas.
  2653. Se incluyen algunas funciones matem\'aticas de transformaci\'on, es
  2654. probable que se incluyan m\'as en el futuro.
  2655. \proto{Fsin(y)}
  2656. \pproto{Fcos(y)}
  2657. \pproto{Ftan(y)}
  2658. Las funciones |sin()|,~\dots\enspace de siempre.  Funcionan con radianes.
  2659. \proto{Fabs(y)}
  2660. Computa el valor absoluto de |y| ($\vert y\vert$).
  2661. \proto{Ffloor(y)}
  2662. \pproto{Fceil(y)}
  2663. Computa el entero m\'as pr\'oximo a |y| (menor y mayor respectivamente).
  2664. \proto{Fexp(y)}
  2665. \pproto{Flog(y)}
  2666. \pproto{Flog10(y)}
  2667. \pproto{Fpow(y,z)}
  2668. \pproto{Fsqrt(y)}
  2669. Computa $e^y$, $\ln y$, $\log_{10} y$, $z^y$ y $\sqrt{y}$.
  2670. \proto{x,n:=RealVal(s)}
  2671. Analiza la cadena  |s|  para producir el valor real  |x|.  No tiene en
  2672. cuenta los espacios o tabuladores que lleve delante.  |n| es el n\'umero de
  2673. caracteres analizados desde el comienzo de la cadena, o |0| si la cadena no
  2674. representa a un valor real.  |x| valdr\'a en ese caso $0.0$.  Acepta  valores
  2675. negativos (e incluso n\'umeros sin |.|).
  2676. \Ejemplos
  2677. Ejemplos:&|RealVal(' 3.14 ')|\qquad resulta $3.14$, $5$\cr
  2678.          &|RealVal('blabla')|\qquad resulta $0.0$, $0$\cr
  2679. \proto{s:=RealF(s,x,n)}
  2680. Retorna en |s| el valor real |x| como cadenaE,  con |n| decimales.  El
  2681. m\'aximo de |n| es |8|,  incluso menos si la parte entera del n\'umero es grande.
  2682. Un valor de |n|  igual a |0|  indicar\'a  que no se quiere fracci\'on.  La
  2683. cadena se retorna como resultado,  para poder utilizarla en un |WriteF()|.
  2684. \Ejemplos
  2685. Ejemplo:&|WriteF('real=\s\n',RealF(s,3.14159),4)|\qquad resulta |real=3.1416|\cr
  2686. \finsma
  2687. |RealF()| se afana en realizar  redondeos razonables para un cierto |n|,
  2688. como  muestra  el ejemplo.  Los n\'umeros negativos tambi\'en son tratados de
  2689. forma correcta.
  2690. \ejemplos
  2691. &|RealF(s,-3.14159,0)|\qquad resulta $-3$\cr
  2692. \seccion Notas sobre la implementaci\'on de los reales.
  2693.    Como se  dijo antes,  el formato de reales de~ E es el {\sc IEEE} (simple),
  2694. esto significa  que el c\'odigo con  reales anterior, que usaba  el formato
  2695. {\sc FFP} con las  funciones |SpXxx| se debe reescribir (como  se indicaba en la
  2696. documentaci\'on de la v2.1b del compilador).  |EC|~v3.0 ya no apoya directamente
  2697. la librer\'{\i}a |mathffp|, y tendr\'as que abrir esta librer\'{\i}a
  2698. directamente si quieres usarla.
  2699. \espacio
  2700. Se eligi\'o {\sc IEEE} simple porque:
  2701. \item{$-$} Los {\sc IEEE} dobles no entran en un |LONG|.
  2702. \item{$-$} Las rutinas del formato {\sc FFP} no utilizan el |68881| si est\'a presente,  las
  2703.   de {\sc IEEE}  s\'{\i}  lo  hacen.   Adem\'as,  el formato {\sc IEEE} es compatible con el
  2704.   |68881|, que tambi\'en utiliza el formato {\sc IEEE}.
  2705. \item{$-$} {\sc IEEE}  es el formato  estandard  para reales,  reconocido  en  todos los
  2706.   lugares,  lo  cual  permite  compatibildad  de ficheros de datos  entre
  2707.   software/plataformas.
  2708. \espacio
  2709. Las  rutinas de  reales  en  E usan  la  mathieeesingbas.library  y la
  2710. mathieeesingtrans.library,  las  cuales no  se  ofrec\'{\i}an  con la  antigua
  2711. versi\'on~1.3  del  sistema operativo.\nota{se sabe que la v3.1 (v40) del
  2712. sistema operativo del Amiga contiene un error en el c\'odigo de {\sc IEEE}.
  2713. Usa un |SetPatch| que lo corrija.}  Esto  quiere decir  que si  quieres
  2714. escribir bajo\b/apoyar  la~v1.3  del sitema operativo,  y quieres  usar los
  2715. reales {\it internos}, debes asegurarte de que esas librer\'{\i}as est\'an presentes
  2716. (paracen estar disponibles, ?`quizas por medio de Commodore?).
  2717. \noin Tanto  |EC|  como los  programas  que  genera  no abren  esas  librer\'{\i}as
  2718. mientras no se usen reales.
  2719. \espacio
  2720. Si falla todo lo dem\'as, siempre  puedes usar otras librer\'{\i}as de reales
  2721. para usar reales bajo~1.3.  Yo recomendar\'{\i}a el m\'odulo |tools/longreal.m|,
  2722. el cual usa dobles.
  2723. \espacio
  2724.    En  un futuro,  es probable  que  |EC| permita  que las  llamadas de  la
  2725. librer\'{\i}a |mathieee|  se substituyan por c\'odigo  de |68881| en l\'{\i}nea  de forma
  2726. transparente.
  2727. \endchapter\saltacap
  2728. \beginchapter Cap\'{\i}tulo 13. Manejo\\de Excepciones
  2729. El mecanismo de excepciones\nota{en E el t\'ermino {\sl excepci\'on} tiene poco que
  2730. ver con  las excepciones  o interrupciones causadas directamente  por los
  2731. procesadores |680x0|.} de E  es b\'asicamente igual al del lenguaje
  2732. ADA;  proporciona una reacci\'on a los errores en tu  programa, y un manejo
  2733. complejo de  recursos.
  2734. \espacio
  2735. Un manejador  de excepciones es un  fragmento de c\'odigo que  se invoca
  2736. cuando sucede un error en tiempo  de ejecuci\'on.  El sistema  en tiempo de
  2737. ejecuci\'on, o t\'u mismo,  puedes {\sl se\~nalar} que algo ha ido mal  (esto es lo
  2738. que se  llama {\sl lanzar una  excepci\'on}),  y luego el sistema en  tiempo de
  2739. ejecuci\'on probar\'a y  buscar\'a el manejador de excepciones apropiado.  Digo
  2740. {\it apropiado}  porque  un programa  puede  tener  m\'as  de un  manejador  de
  2741. excepciones, en todos los niveles del programa.  La siguiente  puede  ser
  2742. la definici\'on de una funci\'on normal (como ya sabemos):
  2743. \ejemplos
  2744. &|PROC bla()|\cr
  2745. &|  /* ... */|\cr
  2746. &|ENDPROC|\cr
  2747. mientras que una funci\'on con un manejador de excepciones puede ser:
  2748. \ejemplos
  2749. &|PROC bla() HANDLE|\cr
  2750. &|  /* ... */|\cr
  2751. &|EXCEPT|\cr
  2752. &|  /* ... */|\cr
  2753. &|ENDPROC|\cr
  2754. donde  el bloque entre |PROC| y |EXCEPT| se ejecuta como siempre, y si no hay
  2755. ninguna  excepci\'on se salta el bloque entre |EXCEPT| y |ENDPROC|, abandonando
  2756. el  procedimiento  en  |ENDPROC|\null{}.   Si  se alcanza alguna excepci\'on, ya sea
  2757. dentro  del  procecimiento,  o  en  cualquier  funci\'on  llamada desde ese
  2758. bloque, se invocar\'a un manejador de excepciones.
  2759. \seccion Uso de la funci\'on |Raise()|.
  2760. Hay muchas  formas de {\sl lanzar} una excepci\'on,  la m\'as sencilla  es por
  2761. medio de la funci\'on |Raise()|:
  2762. \proto{|Raise(IDexcepcion=0)|}
  2763. donde \enspace|IDexcepcion|\enspace es  simplemente una constante que define el tipo de
  2764. excepci\'on, y lo usan los controladores para determinar lo que fue m\'al.
  2765. \begintt
  2766. ENUM NOMEM,NOFILE  /* y otros */
  2767. PROC bla() HANDLE
  2768.   DEF mem
  2769.   IF (mem:=New(10))=NIL THEN Raise(NOMEM)
  2770.   mifunc()
  2771. EXCEPT
  2772.   SELECT exception
  2773.     CASE NOMEM
  2774.       WriteF('!`Sin memoria!\n')
  2775.     /* ... y otras */
  2776.   ENDSELECT
  2777. ENDPROC
  2778. PROC mifunc()
  2779.   DEF mem
  2780.   IF (mem:=New(10))=NIL THEN Raise(NOMEM)
  2781. ENDPROC
  2782. \endtt
  2783. \Espacio
  2784. La variable  |exception|  del manejador siempre contiene el  valor del
  2785. argumento de la llamada al |Raise()| que lo invoc\'o.
  2786. \noin La funci\'on  |Raise()| invoca al manejador  de la funci\'on |bla()|  en ambos
  2787. |New()|,  y retorna correctamente al que hab\'{\i}a llamado a |bla()|.  La llamada
  2788. |New()| de  |mifunc()| habr\'{\i}a llamado a  su manejador de excepciones  si \'esta
  2789. tuviera alguno.  El alcance de un manejador va desde el comienzo del |PROC|
  2790. en que  se define  hasta la  palabra clave  |EXCEPT|,  incluyendo todas las
  2791. llamadas que se hagan desde el procedimiento.
  2792. \espacio
  2793. Esto tiene tres consecuencias:
  2794. \item{$A.$} Los manejadores se organizan de forma recursiva, y el manejador que se
  2795.    invoca se selecciona  dependiendo de las llamadas de  las funciones en
  2796.    tiempo de ejecuci\'on.
  2797. \item{$B.$} Si  se lanza  una excepci\'on  dentro  de  un manejador,  se  invoca  el
  2798.    manejador  de nivel  justamente anterior.  Esta caracter\'{\i}stica  de los
  2799.    manejadores  se  puede usar  para  implementar  esquemas complejos  de
  2800.    reserva  recursiva de  recursos con  gran facilidad,  (como se ver\'a).
  2801. \item{$C.$} Si se lanza una excepci\'on en un nivel en el que no existe un manejador
  2802.    de  menor  nivel  (o  en  programas  que  no  tienen  ning\'un  tipo  de
  2803.    manejadores), se  finaliza el programa.  (es decir, |Raise(x)|  tiene el
  2804.    mismo efecto que |CleanUp(0)|)
  2805. \espacio
  2806. Veamos otras funciones de manejadores:
  2807. \proto{Throw(IDexcepcion,valor)}
  2808. Como |Raise()|,  s\'olo que ahora lleva  un valor arbitrario con ellas.  Y
  2809. luego  se puede  escrutar  ese  valor en  el  manejador  con la  variable
  2810. |exceptioninfo|.
  2811. \proto{ReThrow()}
  2812. No  tiene argumentos.  Simplemente hace  un  |Throw()| con  el valor  de
  2813. excepci\'on actual.  S\'{\i} y solo s\'{\i} es |<>0|
  2814. \seccion Definici\'on de excepciones para funciones predefinidas (|RAISE/IF|).
  2815. Con lo  que vimos hasta ahora  de las excepciones  ya  tenemos grandes
  2816. ventajas  sobre la  forma de  definir  la funci\'on  |error()| de  siempre,
  2817. aunque hay  que escribir demasiado para  comprobrar la igualdad a  |NIL| de
  2818. cada llamada a |New()|.
  2819. \noin El sistema  de manejo  de excepciones  de E  permite la  definici\'on de
  2820. excepciones para todas las funciones de~E  (como |New()|, |OpenW()|, etc.), y
  2821. para todas  las funciones de Librer\'{\i}a  (|OpenLibrary()|, |AllocMem()|, etc.),
  2822. incluso para aquellas que se incluyen como m\'odulos.
  2823. \Espacio
  2824. \ejemplos
  2825. \qquad Sintaxis:&|RAISE |\<IDexception>| IF |\<func> \<comp> \<valor>|, ...|\cr
  2826. la parte que sigue a |RAISE| se puede repetir con una |,|.
  2827. \Ejemplos
  2828. Ejemplo:&|RAISE NOMEM IF New()=NIL,|\cr
  2829.         &|      NOLIBRARY IF OpenLibrary()=NIL|\cr
  2830. la primera l\'{\i}nea quiere decir algo como: {\sl siempre que una llamada a |New()|\/
  2831. resulte en |NIL|, lanza autom\'aticamente la excepci\'on |NOMEM|}.  \<comp>  puede
  2832. ser cualquiera entre  |= <> > < >= <=|.  Tras esta definici\'on, a lo largo
  2833. de nuestros programas podemos escribir:\quad|mem:=New(size)|\quad sin tener  que
  2834. escribir\quad|IF mem=NIL THEN Raise(NOMEM)|.
  2835. \noin F\'{\i}jate que la  \'unica diferencia es que |mem| nunca  recibe un valor si
  2836. el  sistema  invoca  al  manejador:   para cada llamada a |New()| se genera
  2837. c\'odigo que comprueba su resultado y llama a |Raise()| si es necesario.
  2838. \espacio
  2839.    Vamos  a implementar un peque\~no ejemplo que ser\'{\i}a complejo de resolver
  2840. sin  manejo  de  excepciones:   llamamos  a una funci\'on recursivamente, y
  2841. reservamos  un  recurso  en cada llamada (en este caso se reserva memoria
  2842. antes  de  la llamada recursiva, y se libera despu\'es).  ?`Qu\'e ocurre si en
  2843. alg\'un  momento  en la recursi\'on ocurre un fallo severo, y tenemos que dar
  2844. el programa por terminado?  Cierto, al dejar el programa no podr\'{\i}amos (en
  2845. un  lenguaje  convencional)  liberar  todos  los  recursos  reservados en
  2846. niveles  de recursi\'on inferiores, debido a que todos los punteros a tales
  2847. \'areas de memoria se encuentran en variables locales inalcanzables.  En E,
  2848. simplemente  lanzamos una excepci\'on, y lanzamos otra al final del manejador,
  2849. llamando de esta forma recursivamente a los manejadores, y liberando
  2850. todos los recursos.  Ejemplo:
  2851. \begintt
  2852. CONST SIZE=100000
  2853. ENUM NOMEM  /*, ... */
  2854. RAISE NOMEM IF AllocMem()=NIL
  2855. PROC main()
  2856.   reserva()
  2857. ENDPROC
  2858. PROC reserva() HANDLE
  2859.   DEF mem                 -> veamos cuantos bloques de
  2860.   mem:=AllocMem(SIZE,0)   -> memoria se pueden obtener.
  2861.   reserva()               -> realiza la recursion.
  2862. EXCEPT DO
  2863.   IF mem THEN FreeMem(mem,SIZE)
  2864.   ReThrow()        -> llama recursivamente a los manejadores.
  2865. ENDPROC
  2866. \endtt
  2867. \espacio
  2868. Por  supuesto,  esto  es una simulaci\'on de un problema de programaci\'on
  2869. natural,  que  normalmente  es bastante m\'as complejo, y que por ello hace
  2870. m\'as evidente la necesidad del manejo de excepciones.  Hecha un vistazo al
  2871. c\'odigo  fuente de la utilidad \enspace|D.e|\enspace para ver un programa real de ejemplo,
  2872. en el que el manejo de errores se complicar\'{\i}a sin manejo de excepciones.
  2873. \espacio
  2874. El  |DO|  que  va  despu\'es  de  |EXCEPT| indica que en lugar de saltar a
  2875. |ENDPROC|,  el  c\'odigo  principal  simplemente  contin\'ua la ejecuci\'on en el
  2876. manejador  cuando  llega  a  ese  punto.   Tambi\'en fija la excepci\'on a~0.
  2877. Puede ser \'util si en el manejador liberas recursos locales al |PROC|.
  2878. \seccion Uso de |ID| de excepciones.
  2879. En  realidad  un  |ID | de  excepci\'on es un valor de 32-bits normal (por
  2880. supuesto),  y  puedes  pasar  lo que quieras al manejador de excepciones:
  2881. por ej., algunos los usan para pasar cadenas de descripci\'on de errores:
  2882. \ejemplos
  2883. &|Raise('!`No pude abrir la "gadtools.library"!')|\cr
  2884. \finsma
  2885. Sin embargo, si quieres usar las excepciones de una forma expandible y
  2886. deseas  poder  usar m\'odulos futuros que lanzen excepciones sin definir en
  2887. tu programa, sigue las siguientes normas:
  2888. \item{$-$} Usa y define el |ID| 0 como {\sl no error} (finalizaci\'on normal).
  2889. \item{$-$} Usa los IDs 1-10000 para excepciones espec\'{\i}ficas de tu programa.
  2890.   Def\'{\i}nelos como siempre con |ENUM|:
  2891. \itemitem{} |ENUM OK,NOMEM,NOFILE, ...|
  2892. \itemitem{} (|OK| ser\'a 0, y los dem\'as 1+)
  2893. \item{$-$} Los |ID|'s |12336| a |2054847098| (todos formados por letras may\'usculas
  2894.   o min\'usculas  y d\'{\i}gitos entre comillas,  y tienen longitud 2, 3 o 4)
  2895.   est\'an reservados para  excepciones comunes.  Una excepci\'on com\'un es una
  2896.   excepci\'on que no es necesario definir en tu programa,  y  que puede ser
  2897.   usada  por los implementadores de m\'odulos (con  funciones)  para lanzar
  2898.   excepciones: por ejemplo, si dise\~nas  un conjunto de procedimientos que
  2899.   realizan cierta tarea,  puede ser  que desees lanzar excepciones.  Dado
  2900.   que podr\'{\i}as  querer usar esas  funciones en varios programas,  no ser\'{\i}a
  2901.   pr\'actico tener que coordinar los |ID|s con el programa principal, es m\'as,
  2902.   si usas m\'as de un conjunto de funciones (en un m\'odulo, en el futuro)  y
  2903.   cada m\'odulo tuviera un identificador  diferente para {\sl sin memoria}, las
  2904.   cosas se  har\'{\i}an impracticables.  Ah\'{\i} es  donde  entran las excepciones
  2905.   comunes:  el  |ID | com\'un  para  sin-memoria  es  |"MEM"|  (incluyendo  las
  2906.   comillas): cada implementador deber\'{\i}a escribir simplemente
  2907. \itemitem{} |Raise("MEM")|
  2908. \item{} desde cualquier procediemiento, y el programador que use el m\'odulo s\'olo
  2909.   necesita proporcionar un manejador de exepciones que entienda |"MEM"|.
  2910. \espacio
  2911. \item{} Futuros m\'odulos que contengan  conjuntos de funciones especificar\'an las
  2912.   excepciones que pueden alcanzar cada uno de esos  procedimientos,  y si
  2913.   \'estas  coinciden con  los |ID|s  de  otros procedimientos,  la tarea  del
  2914.   programador que tiene  que tratar con excepciones  se ver\'a simplificada
  2915.   significativamente.
  2916. \Ejemplos
  2917. Ejemplos:\cr
  2918. (sistema)\cr
  2919. \esptab
  2920. |"MEM"|&sin memoria\cr
  2921. |"FLOW"|&pila (pr\'acticamente) llena\cr
  2922. |"STCK"|&recolector de residuos con problemas de pila\cr
  2923. |"^C"|&Ruptura por Control-C\cr
  2924. |"ARGS"|&args err\'oneos\cr
  2925. \esptab
  2926. (exec/librerias)\cr
  2927. \esptab
  2928. |"SIG"|&no se pudo reservar se\~nal\cr
  2929. |"PORT"|&no se pudo crear puerto de mensajes\cr
  2930. |"LIB"|&library no disponible\cr
  2931. |"ASL"|&no asl.library\cr
  2932. |"UTIL"|&no utility.library\cr
  2933. |"LOC"|&no locale.library\cr
  2934. |"REQ"|&no req.library\cr
  2935. |"RT"|&no reqtools.library\cr
  2936. |"GT"|&no gadtools.library (similar para las dem\'as)\cr
  2937. \esptab
  2938. (intuition/gadtools/asl/gfx)\cr
  2939. \esptab
  2940. |"WIN"|&fallo al abrir ventana\cr
  2941. |"SCR"|&fallo al abrir pantalla\cr
  2942. |"REQ"|&no se pudo abrir requester\cr
  2943. |"FREQ"|&no se pudo abrir requester de ficheros\cr
  2944. |"GAD"|&no se pudo crear gadget\cr
  2945. |"MENU"|&no se pudo crear menu(s)\cr
  2946. |"FONT"|&problema obteniendo fuente\cr
  2947. \esptab
  2948. (dos)\cr
  2949. \esptab
  2950. |"OPEN"|&no pude abrir fichero/fichero no existe\cr
  2951. |"OUT"|&problemas escribiendo\cr
  2952. |"IN"|&problemas leyendo\cr
  2953. |"EOF"|&fin de fichero no esperado\cr
  2954. |"FORM"|&error en formato de entrada\cr
  2955. |"SEG"|&problemas con loadseg\cr
  2956. \finsma
  2957. \item{} La tendencia general es:
  2958. \itemitem{*} todas las letras may\'usculas para excepciones generales del sistema,
  2959. \itemitem{*} mezcladas para excepciones usadas por m\'as de una aplicaci\'on, pero
  2960.     no suficientemente generales,
  2961. \itemitem{*} todas min\'usculas para excepciones lanzadas dentro  varios  m\'odulos de
  2962.     tu propia aplicaci\'on.
  2963. \item{$-$} Todas los dem\'as, (incluyendo los IDs negativos) estan reservados.
  2964. \endchapter\saltacap
  2965. \beginchapter Cap\'{\i}tulo 14. Programaci\'on\\Orientada\\a Objetos
  2966. Las caracter\'{\i}sticas que se describen en esta secci\'on est\'an agrupadas como
  2967. tal ya que constituyen lo que generalmente se conoce como los tres
  2968. principales componentes esenciales que hacen a un lenguaje 'Orientado a
  2969. objetos' (es decir, herencia--ocultamiento de datos--polimorfismo).  Sin
  2970. embargo, en~E no son un {\it tema independiente} ya que cada uno de ellos se
  2971. puede usar de todas formas junto con otras caracter\'{\i}sticas del~E.
  2972. \seccion Herencia de Objetos.
  2973. Siempre resulta inc\'omodo el no poder expresar dependencias entre |OBJECT|os, o
  2974. reusar c\'odigo que funciona en un |OBJECT|o particular con otro mayor que
  2975. encapsula al primero.  La herencia de objetos en~E permite justamente hacer
  2976. eso.  Cuando tienes un objeto |a|:
  2977. \ejemplos
  2978. &|OBJECT a|\cr
  2979. &\quad|sig, indice, term|\cr
  2980. &|ENDOBJECT|\cr
  2981. puedes crear un nuevo objeto |b|  con las mismas propiedades de |a|
  2982. (y compatible con el c\'odigo que se sirve de |a|):
  2983. \ejemplos
  2984. &|OBJECT b OF a|\cr
  2985. &\quad|bla, x, burp|\cr
  2986. &|ENDOBJECT|\cr
  2987. y que equivale a:
  2988. \ejemplos
  2989. &|OBJECT b|\cr
  2990. &\quad|sig, indice, term,         /* de a */|\cr
  2991. &\quad|bla, x, burp|\cr
  2992. &|ENDOBJECT|\cr
  2993. de  forma  que  con |DEF p:b| podr\'as acceder directamente no s\'olo a |p.bla|
  2994. sino tambi\'en a |p.sig|.
  2995. \espacio
  2996. Por ejemplo, si se tiene un m\'odulo con un |OBJECT|o para implementar un
  2997. cierto tipo de datos con procedimientos de apoyo, (por ejemplo, una lista
  2998. doblemente enlazada) se puede simplemente heredar de ella, a\~nadiendo datos
  2999. propios al objeto, y usar las funciones {\sl existentes} para manipular la
  3000. lista.  Sin embargo la herencia s\'olo ofrece toda su potencia cuando se
  3001. combina con m\'etodos.
  3002. \seccion Ocultamiento de datos (|EXPORT/PRIVATE/PUBLIC|).
  3003. E posee un mecanismo de ocultamiento de datos bastante controlable.  Otros
  3004. lenguajes, como el C++, usan el ocultamiento de datos en clases, lo cual nos
  3005. lleva a la necesidad de trampas (como {\it friends}), y hace el ocultamiento de
  3006. datos inseguro (Eiffel).  El ocultamiento de datos de~E funciona a nivel de
  3007. m\'odulos, lo cual permite modelar el ocultamiento de datos a nivel de clases,
  3008. pero tambi\'en permite esquemas m\'as inteligentes.
  3009. \espacio
  3010.    |PUBLIC|  y  |PRIVATE| declaran visible o no al mundo exterior una secci\'on
  3011. de un objeto;  en este caso, el mundo exterior es todo el c\'odigo ajeno al
  3012. m\'odulo.  Por otra parte, todo es visible para el c\'odigo del m\'odulo. Veamos un
  3013. ejemplo:
  3014. \begintt
  3015. OBJECT misdatos PRIVATE                 -> todo el objeto es privado
  3016.   bla:PTR TO misdatos, burp, grrr:INT
  3017. ENDOBJECT
  3018. OBJECT aaargh
  3019.   blerk:PTR TO aaargh                   -> publico
  3020. PRIVATE
  3021.   x:INT, y:INT, z:INT                   -> privado
  3022. PUBLIC
  3023.   hmpf[10]:ARRAY OF misdatos            -> publico de nuevo
  3024. ENDOBJECT
  3025. \endtt
  3026. Un objeto  es p\'ublico por  omisi\'on, la  aparici\'on de |PRIVATE|  o |PUBLIC|
  3027. actua como interruptor para la visibilidad del objeto en ese momento.  En
  3028. el primer  objeto todo  es privado.  El segundo  s\'olo tiene  (x,y,z) como
  3029. privado.  Las palabras clave |PRIVATE| y |PUBLIC| pueden aparecer:
  3030. \item{$-$} En la l\'{\i}nea de cabecera del objeto.
  3031. \item{$-$} Como l\'{\i}nea en si misma dentro de la definici\'on del objeto.
  3032. \item{$-$} Precediendo declaraciones en la definici\'on del objeto.
  3033. \noin (es decir, pr\'acticamente en cualquier lugar)
  3034. \Espacio
  3035. {\it ?`Por que ocultamiento de datos?}
  3036. \espacio
  3037. Si  quieres saber  por  qu\'e  el ocultamiento  de  datos  es una  buena
  3038. t\'ecnica,  es  probable que quieras  leer alg\'un buen libro de OO\null{}.  Pero en
  3039. resumen: por lo  general se supone que gran cantidad  de los problemas de
  3040. mantenimiento y mejora de fragmentos grandes de c\'odigo  se deben al hecho
  3041. de que resulta  dificil cambiar las cosas, debido a  que gran cantidad de
  3042. c\'odigo empieza a  depender de ciertas estructuras del c\'odigo.  Si ocultas
  3043. un objeto,  s\'olo el c\'odigo dentro del m\'odulo depender\'a del formato de los
  3044. objetos,  y podr\'as  modificar f\'acilmente la representaci\'on de un objeto y
  3045. el c\'odigo que trabaja con \'el  (por ejemplo, podr\'{\i}as cambiar f\'acilmente la
  3046. implementaci\'on  de una  pila de  |ARRAY| a  una lista).  Si gran  parte del
  3047. c\'odigo de  una gran  aplicaci\'on depende del  hecho de que  la pila  es un
  3048. |ARRAY|, no podr\'as cambiarlo con facilidad, lo cual acarrear\'a problemas. En
  3049. resumen, intenta  ocultar tanto  como puedas sin  llegar a  ser demasiado
  3050. restrictivo en  el uso  de tu objeto.  El uso de  m\'etodos te  permitir\'a a
  3051. menudo mantener todo el objeto privado.
  3052. \seccion M\'etodos y m\'etodos virtuales.
  3053. Un  m\'etodo  es  muy parecido a un |PROC|, con la diferencia de que forma
  3054. parte de un |OBJECT|o.  Adem\'as, tambi\'en permite explotar el polimorfismo en
  3055. los objetos, como veremos a continuaci\'on.  Veamos la definici\'on de un m\'etodo:
  3056. \ejemplos
  3057. &|OBJECT blerk PRIVATE|\cr
  3058. &\quad|x:PTR TO blerk, y:INT, z|\cr
  3059. &|ENDOBJECT|\cr
  3060. \Esptab
  3061. &|PROC getx() OF blerk IS self.x|\cr
  3062. la parte |OF blerk| le dice al compilador que pertenece al objeto |blerk|.
  3063. F\'{\i}jate en que, aparte de |OF|, la sintaxis es completamente igual a la de un
  3064. |PROC|, sin embargo, no se puede invocar como tal, y tambi\'en funciona de
  3065. forma diferente.
  3066. \espacio
  3067. |self| es una variable local que est\'a disponible en todo m\'etodo, y es un
  3068. puntero al objeto al que pertenece el m\'etodo (en este caso |self:PTR TO blerk|).
  3069. Esta funci\'on s\'olo retorna el valor de campo |x| de |blerk|, lo cual
  3070. tiene sentido, ya que esto te permite modificar m\'as tarde lo que representa |x|.
  3071. \espacio
  3072. Los m\'etodos se pueden llamar de forma similar a como se hace la selecci\'on de
  3073. objetos ``|.|'':
  3074. \ejemplos
  3075. &|DEF a:PTR TO blerk|\cr
  3076. &|NEW a|\cr
  3077. &| ...|\cr
  3078. &|a.getx()           -> invoca metodo getx() en el objeto a|\cr
  3079. en este ejemplo, sobre la invocaci\'on  |a| toma el valor de |self| durante
  3080. la jecuci\'on de |getx()|.
  3081. \espacio
  3082.    Como  ves,  el uso de m\'etodos es interesante, aunque no hemos visto su
  3083. poder real, el cual s\'olo aparece cuando se usa junto con la herencia.
  3084. \espacio
  3085.    Si heredo  un objeto  que tiene m\'etodos,  de forma  autom\'atica obtengo
  3086. esos m\'etodos en el nuevo objeto:
  3087. \begintt
  3088. OBJECT burp OF blerk PRIVATE   -> como blerk, + campo extra
  3089.   prut:INT
  3090. ENDOBJECT
  3091. DEF b:PTR TO burp
  3092. NEW b
  3093. b.getx()                       -> mismo metodo
  3094. \endtt
  3095. \espacio
  3096. Lo interesante  viene ahora,  ya que  en lugar  de heredar  un m\'etodo,
  3097. tambi\'en puedes redefinirlo:
  3098. \ejemplos
  3099. &|PROC getx() OF burp IS self.x+1|\cr
  3100. (no hace falta decir que tambi\'en puedes a\~nadir nuevos m\'etodos)
  3101. \espacio
  3102.    As\'{\i}   que,  cuando  sea  apropiado,  puedes  optar  por  modificar  el
  3103. funcionamiento  de  los  m\'etodos que obtenemos de otros objetos, mientras
  3104. que el interface a \'el (en este caso |getx()|) se mantiene igual.  Esto no
  3105. s\'olo  permite  la  reutilizaci\'on  del  c\'odigo de forma selectiva, tambi\'en
  3106. podemos hacer uso del polimorfismo:
  3107. \ejemplos
  3108. &|PROC hazalgo(o:PTR TO blerk)|\cr
  3109. &|  ...|\cr
  3110. &|  o.getx()|\cr
  3111. &|  ...|\cr
  3112. &|ENDPROC|\cr
  3113. \Esptab
  3114. &|hazalgo(a)|\cr
  3115. &|hazalgo(b)|\cr
  3116. podemos  llamar  a este |PROC| tanto con |a| como con |b|, ya que ambos son
  3117. compatibles con un objeto |blerk|.  Aunque, ?`Cual de las dos implementaciones
  3118. de |getx()| se invoca con |o.getx()|?\qquad Repuesta:\quad las dos.  Las llamadas
  3119. a m\'etodos en~E son lo que se llaman m\'etodos virtuales en otros lenguajes:
  3120. act\'uan  din\'amicamente  en  el tipo real del objeto (|o|) y llaman al m\'etodo
  3121. apropiado.
  3122. \espacio
  3123. Un ejemplo m\'as claro:
  3124. \ejemplos
  3125. &|-> Ejemplo clasico de polimorfismo OO|\cr
  3126. \esptab
  3127. &|OBJECT loc|\cr
  3128. &|  PRIVATE posx:INT, posy:INT|\cr
  3129. &|ENDOBJECT|\cr
  3130. \esptab
  3131. &|OBJECT punto OF loc|\cr
  3132. &|  PRIVATE color:INT|\cr
  3133. &|ENDOBJECT|\cr
  3134. \esptab
  3135. &|OBJECT circulo OF punto|\cr
  3136. &|  PRIVATE rados:INT|\cr
  3137. &|ENDOBJECT|\cr
  3138. \esptab
  3139. &|PROC muestra() OF loc IS WriteF('!`Soy una Localizacion!\n')|\cr
  3140. &|PROC muestra() OF punto IS WriteF('!`Soy un Punto!\n')|\cr
  3141. &|PROC muestra() OF circulo IS WriteF('!`Soy un Circulo!\n')|\cr
  3142. \esptab
  3143. &|PROC main()|\cr
  3144. &|  DEF x:PTR TO loc,l:PTR TO loc,p:PTR TO punto,c:PTR TO circulo|\cr
  3145. &|  ForAll({x},[NEW l,NEW p,NEW c],`x.muestra())|\cr
  3146. &|ENDPROC|\cr
  3147. aqu\'{\i} |x| es un |PTR TO loc|,  por lo que podr\'{\i}as esperar que |x.muestra()|
  3148. escribiera |!`Soy una Localizacion!| tres veces, pero en su lugar escribe la
  3149. cadena correcta para cada objeto.
  3150. \espacio
  3151. Si  quisieramos  escribir esto en un lenguaje no OO, necesitar\'{\i}amos un
  3152. |SELECT|  para  cada  operaci\'on  como  |muestra()|,  comprobando cierto valor
  3153. presente  en  el  objeto para ver de qu\'e tipo es.  Si quisiera a\~nadir una
  3154. nueva forma a las anteriores, como:
  3155. \ejemplos
  3156. &|OBJECT elipse OF circulo|\cr
  3157. necesitar\'{\i}a cambiar  todos los |SELECT|s a  lo largo de la  aplicaci\'on para
  3158. que  lo tengan  en cuenta.  Con el  polimorfismo de objetos,  simplemente
  3159. escribir\'{\i}a  un m\'etodo |muestra()|,  y  {\bf todo} el c\'odigo de  la aplicaci\'on que
  3160. llame a |x.muestra()| actuar\'{\i}a correctamente cuando |x| sea un |PTR TO elipse|,
  3161. !`incluso sin tener que recompilar!
  3162. \noin Es dificil mostrar  el poder de esto en unos  pocos ejemplos, la mejor
  3163. forma de  descubrirlo es  us\'andolo en aplicaciones  reales, y:  como dije
  3164. antes, leyendo un libro sobre ello.
  3165. \Espacio
  3166. {\it ?`C\'omo funciona el polimorfismo?}
  3167. \noin En los ejemplos anteriores, est\'a claro que el compilador no sabe a qu\'e
  3168. m\'etodo  llamar\'a.  Ese es el motivo por el cual~E usa un {\it objeto clase}, y
  3169. cada  objeto creado obtiene un puntero a este objeto.  En el objeto clase
  3170. se  guarda  toda  la  informaci\'on que es com\'un a todos los objetos de ese
  3171. tipo,  tales  como  punteros a m\'etodos.  Cuando el compilador detecta una
  3172. llamada  como |x.muestra()|, en lugar de mirar directamente en la |muestra()|
  3173. que  pertenece  al  tipo  de  |x| (es decir |loc|), generar\'a c\'odigo que llama
  3174. autom\'aticamente  a la |muestra()| de punto, cuando |x| es realmente un objeto
  3175. punto.  Esto recibe a veces el nombre de enlace en tiempo de ejecuci\'on.
  3176. \noin Los objetos que tienen m\'etodos son, por tanto,  4~bytes mayores de  lo
  3177. esperado,  ya  que  contienen  un puntero al objeto clase.  El puntero lo
  3178. inicializa  autom\'aticamente  |NEW|, raz\'on por la que {\it de momento} |NEW| es la
  3179. \'unica forma de crear tales tipos de objetos.
  3180. \espacio
  3181. Si un  m\'etodo se declara  con el \'unico  prop\'osito de permitir  que las
  3182. subclases  lo  redefinan (este  tipo  de  clases  se conocen  en  algunos
  3183. lenguajes como clases bases virtuales), se puede usar |EMPTY|:
  3184. \ejemplos
  3185. &|PROC bla() OF obj IS EMPTY|\cr
  3186. entonces  se  puede  redefinir  en  las subclases.  Dado que puede que el
  3187. programador  no  implemente  todos los m\'etodos de una vez, no es un error
  3188. que se ejecute el m\'etodo anterior.  Simplemente retornar\'a |0| o |NIL|.
  3189. \espacio
  3190. Se pueden a\~nadir m\'etodos a los |OBJECT|os del sistema:
  3191. \ejemplos
  3192. &|OBJECT migadget OF gadget       -> !`de intuition!|\cr
  3193. &|  -> campos extra aqui|\cr
  3194. &|ENDOBJECT|\cr
  3195. &|PROC creategadget() OF migadget IS ...|\cr
  3196. \finsma
  3197. Un puntero a un objeto como \'este es compatible con el puntero normal a
  3198. |gadget|, es decir, se puede a\~nadir directamente a un ventana, etc~\dots
  3199. \seccion Constructores, Destructores y Super-M\'etodos.
  3200. El  constructor puede tener un nombre cualquiera, aunque suele darsele
  3201. el mismo nombre que la clase.  Incluso se pueden tener varios constructores
  3202. para  una  misma  clase.  El constructor se llama directamente en un
  3203. objeto creado con |NEW|:
  3204. \ejemplos
  3205. &|NEW obj.pila()|\cr
  3206. \finsma
  3207. Sin  embargo,  los  destructores deben llamarse |end|.  Y el objeto se
  3208. destruye con:
  3209. \ejemplos
  3210. &|END obj|\cr
  3211. y si |obj| tiene un m\'etodo |end()|, se le llama de forma autom\'atica.  |end()|
  3212. no debe tener argumentos, y no tiene sentido que retorne un valor.
  3213. \Espacio
  3214. El super-m\'etodo de un m\'etodo es el m\'etodo de su super-clase con el mismo
  3215. nombre.  Algunas veces es \'util llamar a este m\'etodo para incluir su
  3216. comportamiento al de tu clases, sin embargo, debido a que lo has redefinido,
  3217. el llamar al super-m\'etodo por su nombre simplemente se llamar\'{\i}a a s\'{\i} mismo.
  3218. La palabra clave |SUPER| te permite llamar a cualquier m\'etodo de tu
  3219. super-clase (o la super-clase de algun otro):
  3220. \ejemplos
  3221. &|SUPER obj.metodo()|\cr
  3222. este  fragmento  de c\'odigo se puede usar como expresi\'on y como sentencia.
  3223. Sin embargo, hay que tener cuidado, ya que si el superm\'etodo llama a otro
  3224. m\'etodo de ese objeto, llamar\'a a la versi\'on redefinida, no la de su propio
  3225. {\it nivel}  (aunque  eso  suele  ser lo que queremos).  Adem\'as, el compilador
  3226. mira  el  tipo est\'atico de |obj| para encontrar su superclase, no el tipo
  3227. din\'amico (aunque pueda tener ese resultado).
  3228. \endchapter\saltacap
  3229. \beginchapter Cap\'{\i}tulo 15. Ensamblador\\en-l\'{\i}nea
  3230. Como habr\'as apreciado en el ejemplo de Mnemot\'ecnicos ensamblador, las
  3231. instrucciones en ensamblador se pueden mezclar libremente con c\'odigo~E\null{}.
  3232. El gran secreto es que el compilador incluye un ensamblador completo.
  3233. \espacio
  3234. Adem\'as de los modos de direccionamiento normales del ensamblador, puedes
  3235. usar los siguientes identificadores del E:
  3236. \begintt
  3237. mietiqueta
  3238. LEA mietiqueta(PC),A1 /* etiquetas */
  3239. DEF a                 /* variables */
  3240. MOVE.L (A0)+,a        /* fijate que <var> es <offset>(A4) (o A5) */
  3241. MOVE.L dosbase,A6     /* identificadores de llamada a library */
  3242. JSR    Output(A6)
  3243. MOVEQ  #TRUE,D0       /* constantes */
  3244. \endtt
  3245. \espacio
  3246. El ensamblador de |EC| permite las siguientes construcciones, en las cuales:
  3247. \ejemplos
  3248. \qquad $n$&   = numregistro\cr
  3249. \qquad $x$&   = \'{\i}ndice\cr
  3250. \qquad $lab$& = etiqueta, de: ``|etiqueta:|'' o ``|PROC etiqueta()|''\cr
  3251. \qquad $abs$& = direcci\'on absoluta\cr
  3252. \qquad $s$&   = tama\~no. \enspace|L|, |W| o |B|, el que sea apropiado.\cr
  3253. \finsma
  3254. \item{$-$} modos de direccionamiento que permite |EC|:
  3255. \itemitem{} |D|$n$, |A|$n$, |(A|$n$|)|, |(A|$n$|)+|, |-(A|$n$|)|, $x$|(A|$n$|)|, $x$|(A|$n$|,D|$n$|.|$s$|)|,
  3256.             $lab$|(PC)|, $lab$|(PC,D|$n$|.|$s$|)|, $abs$, $abs$|.W|\nota{escribe $abs$|.W| en
  3257.             hexadecimal,  para no confundirlo con un valor real, es
  3258.             decir escribe  |MOVE.L $4.W,A6|}
  3259. \espacio
  3260. \item{$-$} permitidos parcialmente:
  3261. \itemitem{} |#|\<expconst>
  3262. \espacio
  3263. \item{$-$} no permitidos:
  3264. \itemitem{} $lab$ (igual que $abs$), |#|$lab$
  3265. \itemitem{} usa |LEA |$lab$|(PC),A|$n$  en su lugar.
  3266. \espacio
  3267. \item{$-$} modos extra:
  3268. \itemitem{} \<var>|.|$s$ (transfiere contenido de \<var>.$s$ puede ser |.W| o |.B|,
  3269.             por omisi\'on es |.L|)
  3270. \itemitem{} FuncionDeLibreria(A6)
  3271. \espacio
  3272. ejemplo:
  3273. \begintt
  3274. MOVE.W mivar.W,D0     -> mueve palabra baja de 'mivar'
  3275. MOVE.L dosbase,A6
  3276. JSR    Write(A6)
  3277. \endtt
  3278. \espacio
  3279. Adem\'as, E permite que las funciones retornen directamente un registro:
  3280. \ejemplos
  3281. &|ENDPROC D0|\cr
  3282. y  tambi\'en  puedes  interpretar esto c\'omo valores de retorno m\'utiples, es
  3283. decir |D0/D1/D2|.
  3284. \seccion El ensamblador en l\'{\i}nea comparado con un macro ensamblador.
  3285. De alguna forma el ensamblador en-l\'{\i}nea se diferencia del macro-ensamblador
  3286. de siempre, debido principalmente al hecho de que es una extensi\'on de~E, y
  3287. por tanto sigue la sintaxis de~E\null{}.  Las principales diferencias son estas:
  3288. \espacio
  3289. \item{$-$} los comentarios se hacen con |/* */| y no ``|;|'',  y su significado es
  3290.   ligeramente distinto.
  3291. \item{$-$} las palabras clave  y los registros van en may\'usculas,  todo depende de
  3292.   si va en may\'usculas o min\'usculas.
  3293. \item{$-$} no hay macros ni otros lujos de los ensambladores  (bueno, est\'a todo el
  3294.   lenguaje~E para cubrir esto~\dots)
  3295. \item{$-$} debes tener en cuenta que los registros |A4/A5|  no se deben ensuciar con
  3296.   el  c\'odigo en ensamblador, ya que los utiliza el c\'odigo~E, si tu c\'odigo
  3297.   se  puede  llamar  desde  c\'odigo que reserva registros, debes preservar
  3298.   |D3-D7|.  La siguiente instrucci\'on puede ayudar en caso de problemas:
  3299. \itemitem{} |MOVEM.L D3-D7,-(A7); /*ensamblador en linea*/; MOVEM.L (A7)+,D3-D7|
  3300. \item{$-$} {\bf Todavia} no se permite  modelo |LARGE/hunk-reloc|  en ensamblador.  Esto
  3301.   quiere decir que  de  momento  debes usar  direccionamiento
  3302.   relativo a |PC| (que de todas formas es m\'as r\'apido).
  3303. \seccion Utilizaci\'on de datos binarios (|INCBIN/CHAR...|).
  3304. \Ejemplos
  3305. \qquad Sintaxis:&|INCBIN |\<fichero>\cr
  3306. incluye el fichero binario en el punto exacto de la sentencia,  por tanto
  3307. debe separase del c\'odigo.  Por ejemplo:
  3308. \ejemplos
  3309. &|mitab: INCBIN 'df1:data/blabla.bin'|\cr
  3310. \Espacio
  3311. \ejemplos
  3312. \qquad Sintaxis:&|LONG |\<valores>|, ...|\cr
  3313.          &|INT |\<valores>|, ...|\cr
  3314.          &|CHAR |\<valores>|, ...|\cr
  3315. te permite colocar datos binarios directamente en  el programa.  Funciona
  3316. como |DC.|$x$  en ensamblador.  Se\~nalar que la sentencia |CHAR|  tambi\'en recibe
  3317. cadenas, y siempre estar\'an alineados a direcciones pares.  Ejemplo:
  3318. \ejemplos
  3319. &|misdatos: LONG 1,2; CHAR 3,4,'!`Que hay amigos!',0,1|\cr
  3320. \seccion OPT ASM.
  3321. |OPT ASM| tambi\'en se discute en el apartado sobre  |OPT|\null{}.  Permite  operar
  3322. con |EC| como si fuera un ensamblador.  No hay ninguna raz\'on para usar |EC|
  3323. en lugar de otros macro-ensambladores, a excepci\'on de que es significativamente
  3324. m\'as r\'apido que  por ejemplo A68k, as\'{\i} como DevPac,  y pierde  con
  3325. respecto a AsmOne (sniff |8-{|).  Tambi\'en ser\'a tedioso el pasar los  viejos
  3326. discos con fuentes de Seka por |EC|, debido a las diferencias descritas con
  3327. anterioridad.  Si quieres  escribir programas  en ensamblador con  |EC|,  y
  3328. quieres mantener tus fuentes compatibles con otros ensambladores, simplemente
  3329. precede todos los elementos espec\'{\i}ficos de~E  con un  ``|;|'', |EC|~los
  3330. usar\'a, y cualquier otro ensamblador los tomar\'a como comentarios.  Empieza
  3331. los comentarios normales con un smiley (|;->|).  Por ejemplo:
  3332. \ejemplos
  3333. &|; OPT ASM|\cr
  3334. &|comienzo:  MOVEQ   #1,D0           ;-> haz algo tonto|\cr
  3335. &|           RTS                     ;-> y sal|\cr
  3336. esto lo ensamblar\'a cualquier ensamblador, incluyendo |EC|.
  3337. \seccion Ensamblador en l\'{\i}nea y variables registro.
  3338. Las variables registro son una buena ayuda al ensamblador en l\'{\i}nea, ya
  3339. que  funcionan como registros, aunque al mismo tiempo tienen un identificador
  3340. claro  en lugar de Dx, y adem\'as, el c\'odigo de E los guarda y recupera
  3341. de forma autom\'atica.  Por ejemplo:
  3342. \ejemplos
  3343. &|PROC bla()|\cr
  3344. &|  DEF count:REG|\cr
  3345. &|  MOVEQ #10,cuenta|\cr
  3346. &|bucle: WriteF('cuenta=\d\n',cuenta)|\cr
  3347. &|  DBRA cuenta,bucle|\cr
  3348. &|ENDPROC|\cr
  3349. todas las instrucciones que funcionan  con |Dx EA| funcionan  con variables
  3350. registro:
  3351. \ejemplos
  3352. &|MOVEQ #1,a|\cr
  3353. &|MOVEM.L D0/D1/a/b/A0,-(A7)|\cr
  3354. &|LSL.L a,b|\cr
  3355. &| ....|\cr
  3356. como se  sabe, |EC|  usa los registros |D3-D7|  para estas  variables registro.
  3357. Si quieres escribir c\'odigo que mezcle libremente ensamblador con~E,  es
  3358. recomendable mantener  variables  usadas  con  frecuencia  en  variables  registro,  y
  3359. temporales en |D0-D2|/|A0-A3|/|A5|.
  3360. \endchapter\saltacap
  3361. \beginchapter Cap\'{\i}tulo 16. Notas T\'ecnicas
  3362. \seccion La palabra clave OPT.
  3363. \Ejemplos
  3364. \qquad Sintaxis:&|OPT |\<opciones>|, ...|\cr
  3365. \finsma
  3366. Te permite cambiar alg\'un funcionamiento del compilador:
  3367. \smallskip
  3368. \vbox{\halign{{\tt#}\hfil&
  3369.          \quad\vtop{\parindent=0pt\hsize=24pc\hangindent=0pt\strut#\strut}\cr
  3370. LARGE&Fija el modelo de c\'odigo y datos en grande (|LARGE|).  Por
  3371.                 omisi\'on es  peque\~no (|SMALL|);  El compilador suele generar
  3372.                 c\'odigo relativo a~|PC|, con un tama\~no m\'aximo de~32k.  |LARGE|
  3373.                 no pone tales l\'{\i}mites, y genera bloques (hunks) reloc.\cr
  3374. STACK=x&Fija el tama\~no de la pila a |x|~bytes.  \'Usalo siendo consciente de lo
  3375.                 que haces.  Normalmente  el  compilador  hace  una  buena
  3376.                 estimaci\'on del espacio de pila que se necesita.\cr
  3377. ASM&Pone el compilador en modo  ensamblador.  A partir de ese
  3378.                 momento  s\'olo se  permiten instrucciones  en ensamblador,
  3379.                 y no se genera c\'odigo de inicializaci\'on.\cr
  3380. NOWARN&Elimina  las  advertencias.  El compilador  te avisar\'a si 
  3381.                 {\sl piensa}  que  tu  programa  es  incorrecto,  aunque  sea
  3382.                 sint\'acticamente correcto.\cr
  3383. DIR=dirmodulos&Indica el directorio en  el que el compilador buscar\'a los
  3384.                 m\'odulos,  por omisi\'on es |EMODULES:|.\cr
  3385. OSVERSION=vers&Por  omisi\'on es 33 (v1.2).  Fija  la  versi\'on m\'{\i}nima de  KickStart
  3386.                 (como  37 para  v2.04) bajo  la que  funcionar\'a tu
  3387.                 programa.  De esta forma, tu programa fallar\'a al abrir la
  3388.                 dos.library  en el  c\'odigo  de  inicializaci\'on cuando  tu
  3389.                 c\'odigo  se  ejecuta  en  m\'aquinas  anteriores.  De  todas
  3390.                 formas, es  de m\'as utilidad  al usuario si  compurebas la
  3391.                 versi\'on t\'u mismo y das un mensaje de error apropiado.\cr
  3392. MODULE&Indica que este c\'odigo es un m\'odulo.\cr
  3393. EXPORT&Exporta autom\'aticamente las declaraciones del m\'odulo.\cr
  3394. RTD&Genera RTDs en vez de RTS en fuente principal. S\'olo |020+|.\cr
  3395.    &({\it optimizaci\'on experimental\/})\cr
  3396. 020,881,040&Genera c\'odigo para esa CPUs. Aun no utilizable.\cr
  3397. REG=n&Usa |n| registros para reserva de registros.\cr
  3398. \Ejemplos
  3399. Ejemplo:&|OPT STACK=20000,NOWARN,DIR='df1:modules',OSVERSION=39,REG=3|\cr
  3400. \finsma
  3401. \seccion Modelo SMALL/LARGE.
  3402. \E/ te permite  elegir entre modelo de datos\b/c\'odigo |SMALL| y  |LARGE|\null{}.
  3403. F\'{\i}jate que la  mayor\'{\i}a de los programas que  escribir\'as (especialmente si
  3404. acabas de empezar con~E) entrar\'an en~32KB al compilarlos:  no tendr\'as que
  3405. preocuparte  de poner  alg\'un modelo  de  generaci\'on de  c\'odigo.  Te dar\'as
  3406. cuenta de la  necesidad de un modelo  |LARGE| tan pronto como  |EC| empieze a
  3407. quejarse de  que ya  no puede poner tu c\'odigo en~32KB\null{}.  Para compilar un
  3408. fuente con modelo |LARGE|:
  3409. \ejemplos
  3410. &|1> ec -l grande.e|\cr
  3411. o mejor incluso, incluye la sentencia
  3412. \ejemplos
  3413. &|OPT LARGE|\cr
  3414. al principio de tu c\'odigo.
  3415. \seccion Organizaci\'on de la pila.
  3416. Para guardar las variables locales y globales, el sistema en tiempo de
  3417. ejecuci\'on de un ejecutable generado por AmigaE reserva un bloque de memoria,
  3418. del  cual  tomar\'a una parte fija para almacenar todas las variables
  3419. globales.   El  resto  se usar\'a din\'amicamente seg\'un se vayan llamando las
  3420. funciones.   Cuando se llama a una funci\'on en~E, se reserva espacio en la
  3421. pila  para  almacenar todos sus datos locales, el cual se libera al salir
  3422. de  la  funci\'on.   Ese  es el motivo por el que tener arreglos grandes de
  3423. datos locales puede se peligroso cuando se usa recursivamente:  todos los
  3424. datos  de las llamadas anteriores a la misma funci\'on siguen estando en la
  3425. pila  y  utilizan  partes  grandes  del  espacio  libre  de la pila.  Sin
  3426. embargo,  si  los  procedimientos  se  llaman de una forma lineal, no hay
  3427. motivo para que la pila se llene. 
  3428. \espacio
  3429. El sistema en tiempo de ejecuci\'on siempre reserva 10k~extra por encima
  3430. de  esto para  una  recursi\'on  normal (por  ejemplo  con arreglos locales
  3431. peque\~nos)  y  buffers  y  espacio  de  sistema  adicionales,  por  lo que
  3432. reservar\'a 24k de espacio de pila.
  3433. \seccion L\'{\i}mites fijos.
  3434. \medskip
  3435. \vbox{\halign{#\hfil&\quad#\hfil\cr
  3436. \bartab
  3437. OBJETO/ELEMENTO&TAMA\~NO/CANTIDAD/MAX\cr
  3438. \bartab
  3439. valor |CHAR|&                                   $0\ldots 255$\cr
  3440. valor |INT|&                                    $-32$ Kb\dots $+32$ Kb\cr
  3441. valor |LONG|/|PTR|&                             $-2$ Gb\dots $+2$ Gb\cr
  3442. \Esptab
  3443. logitud identificador&                          $100$ bytes$^\infty$\cr
  3444. logitud l\'{\i}nea de c\'odigo&                        $2000$ tokens l\'exicos$^\simeq$\cr
  3445. logitud c\'odigo&                                 $2$ Gb (te\'oricamente)\cr
  3446. listas constantes&                              algunos cientos de elementos$^\simeq$\cr
  3447. cadenas constantes&                             $1000$ caracteres$^\infty$\cr
  3448. anidamiento m\'aximo de bucles (|IF|, |FOR| etc.)&$500$ niveles\cr
  3449. anidamiento m\'aximo de comentarios&              $\infty$\cr
  3450. \Esptab
  3451. n\'umero de variables locales por procedimiento&  $8000$\cr
  3452. n\'umero de variables globales&                   $7500$\cr
  3453. n\'umero de argumentos a funciones propias&       $8000$ (junto con locales)\cr
  3454. n\'umero argumentos funciones varargs de E (|WriteF()|)&$64$ (v2.1) / $1024$ (v2.5)\cr
  3455. \Esptab
  3456. un  objeto (reservado local/global o din\'amico)& $8$ Kb\cr
  3457. un  arreglo, lista o cadena (local o global)&   $32$ Kb\cr
  3458. una cadena (din\'amicamente)&                     $32$ Kb\cr
  3459. una lista (din\'amicamente)&                      $128$ Kb\cr
  3460. un  arreglo (din\'amicamente)&                    $2$ Gb\cr
  3461. objetos con |NEW|&                              $64$ Kb elementos\cr
  3462. |CHAR|/|INT|/|LONG| con |NEW|&                  $2$ Gb\cr
  3463. \Esptab
  3464. datos locales por procedimiento&                $250$ Mb\cr
  3465. datos globales&                                 $250$ Mb\cr
  3466. \Esptab
  3467. tama\~no c\'odigo de un prodeciemiento&             $32$ Kb\cr
  3468. tama\~no c\'odigo del ejecutable&                   |SMALL| $32$ k, |LARGE| $2$ Gb\cr
  3469. l\'{\i}mite pr\'actico actual (puede cambiar)&         $2-5$ (v2.1) / $10$ Mb (v2.5)\cr
  3470. \Esptab
  3471. tama\~no buffer de c\'odigo generado e identific.&  relativo al fuente\cr
  3472. tama\~no buffer de etiquetas/saltos e intermed.&  (re)reservado independ.\cr
  3473. \bartab
  3474. \espacio
  3475. {\eightpoint
  3476. \noin {$\simeq$} valor aproximado, depende de la situaci\'on.\par
  3477. \noin {$\infty$} el valor no tiene l\'{\i}mite claro, pero este parece razonable.\par
  3478. \seccion Mensajes de error, advertencias y comprobaci\'on de no referencia.
  3479. \subsec Comprobaci\'on de no referencia. Al compilar tu c\'odigo fuente con |EC|,
  3480. algunas veces obtienes un mensaje del tipo:
  3481. \ejemplos
  3482. &|UNREFERENCED: |\<ident>, \<ident>|, ...|\cr
  3483. que aparece cuando declaras variables, funciones o etiquetas, y luego no
  3484. las usas.  Este servicio extra que te ofrece el compilador te puede dar
  3485. alguna buena pista sobre todos esos errores dif\'{\i}ciles de detectar.
  3486. \subsec Advertencias. Suelen indicar cosas que pueden ir mal, aunque realmente
  3487. no es un error.
  3488. \adver 'A4/A5 used in inline assembly'
  3489.   'A4/A5 usado en ensamblador en l\'{\i}nea'
  3490.   Esta es la advertencia que obtendr\'as  cuando usas los registros A4 o A5
  3491.   en tu c\'odigo ensamblador.  El motivo de esto es  que esos registros los
  3492.   usa E  internamente para direccionar  las variables globales  y locales
  3493.   respectivamente.  Por  supuesto,  puede  haber  una  buena  raz\'on  para
  3494.   utilizarlos,  como hacer  un  |MOVEM.L A4/A5,-(A7)|  antes  de una  parte
  3495.   grande de ensamblador en l\'{\i}nea.
  3496. \adver 'keep an eye on your stacksize'
  3497.   'hecha un ojo al tama\~no de la pila'
  3498. \fadver
  3499. \adver 'stack is definitely too small'
  3500.   'la pila es definitivamente muy peque\~na'
  3501.   Ambas  pueden ser  provocadas  por  el uso  de  |OPT STACK=|\<tama\~no>.  El
  3502.   compilador simplemente contrastar\'a tu  \<tama\~no>  con su  {\it estimaci\'on},  y
  3503.   escribir\'a la primera advertencia si piensa que est\'a bien aunque un poco
  3504.   ajustado,  y la \'ultima si probablemente es muy peque\~no.
  3505. \adver 'suspicious use of |"="| in void expressions (s). (line \%d)'
  3506.   'uso sospechoso de |"="| en expersiones void (s). (l\'{\i}nea \%d)'
  3507.   Esta advertencia  aparece si escribes expresiones  como |a=1|  como una
  3508.   sentencia.  La raz\'on  de esto  es que  una comparaci\'on  no tiene  mucho
  3509.   sentido  como sentencia,  aunque la  raz\'on principal  es que  puede ser
  3510.   motivo del frecuente error tipogr\'afico de |a:=1|.  Puede ser dificil de
  3511.   encontrar el olvido de ``|:|'',  y puede tener consecuencias desastrosas.
  3512. \adver 'module changed |OPT| settings'
  3513.   'el m\'odulo cambi\'o las opciones |OPT|'
  3514.   Si usas un m\'odulo que usa |OPT OSVERSION=37|,  \'esta  tambi\'en  afectar\'a al
  3515.   programa principal.  La advertencia  te avisa de \'esto.  Para eliminarla
  3516.   s\'olo tienes que poner un |OPT| del mismo tipo en el programa principal.
  3517. \adver 'variable used as function'
  3518.   'variable usada como funci\'on'
  3519.   En  v3,  cualquier  variable  se  puede usar  como  una  funci\'on.  Esta
  3520.   advertencia est\'a para {\it avisarte} por si lo haces de forma accidental.
  3521. \adver 'code outside |PROC|s'
  3522.   'c\'odigo fuera de |PROC|s'
  3523.   Has escrito c\'odigo entre |PROC|s, lo cual es de rara utilidad.
  3524. \Espacio
  3525. \subsec Errores.
  3526.    El compilador escribir\'a la l\'{\i}nea de c\'odigo fuente que caus\'o el error a
  3527. continuaci\'on de \'este,  y un cursor en el punto exacto del error.  El cursor
  3528. denota el punto en el que se hallaba el compilador cuando {\it descubri\'o}
  3529. el  error,  por lo que parece l\'ogico pensar que el s\'{\i}mbolo que provoc\'o el
  3530. error es el que est\'a justo {\it antes} del cursor.
  3531. \parindent=4em
  3532. \error 'Sintaxis error'
  3533.   'Error de sintaxis'
  3534.   El error m\'as com\'un.  Este error aparece tanto cuando  no hay otro error
  3535.   apropiado, como cuando la estructura de tu c\'odigo es demasiado anormal.
  3536. \error 'unknown keyword/const'
  3537.   'palabra clave/constante desconocida'
  3538.   Has utilizado un identificador en may\'usculas (como |IF| o |TRUE|), y el
  3539.   compilador no pudo encontrar una definici\'on de \'el. Causas:\hfil\break
  3540.   $\bullet$ palabra clave mal escrita\hfil\break
  3541.   $\bullet$ usaste una constante, pero olvidaste definirla en una sentencia |CONST|\hfil\break
  3542.   $\bullet$ te olvidaste de indicar el m\'odulo en el que se define la constante
  3543. \error '|":="| expected'
  3544.   'se esperaba |":="|'
  3545.   Has escrito  una sentencia  |FOR| o  de asignaci\'on,  y pusiste  otra cosa
  3546.   diferente de |:=| en su lugar.
  3547. \error 'unexpected characters in line'
  3548.   'caracteres en la l\'{\i}nea no esperados'
  3549.   Usaste caracteres  que no  tienen significado  sint\'actico fuera  de una
  3550.   cadena.  Por ejemplo: |@!&\~|
  3551. \error 'label expected'
  3552.   'se esperaba una etiqueta'
  3553.   En algunos puntos,  por ejemplo  despu\'es de la palabra clave |PROC| o |JUMP|, se
  3554.   pide un identificador de etiqueta,  y escribiste algo diferente.
  3555. \error '|","| expected'
  3556.   'se esperaba |","|'
  3557.   Al  especificar  una lista  de  elementos  (por  ejemplo una  lista  de
  3558.   par\'ametros), escribiste algo que no era una coma.
  3559. \error 'variable expected'
  3560.   'se esperaba una variable'
  3561.   Por ejemplo en:\qquad|FOR |\<var>|:= ...| etc.
  3562. \error 'value does not fit in 32 bit'
  3563.   'el valor no entra en 32 bits'
  3564.   Al especificar una constante diste un n\'umero demasiado grande, como:
  3565.   \quad|$FFFFFFFFF|, |"abcdef"|.  Tambi\'en ocurre cuando defines  un |SET|
  3566.   con m\'as de 32~elementos.
  3567. \error 'missing apostrophe/quote'
  3568.   'falta ap\'ostrofe/comilla'
  3569.   Te olvidaste del |'| al final de una cadena.
  3570. \error 'incoherent program structure'
  3571.   'estrutura de programa incoherente'
  3572.   $\bullet$ empezaste un nuevo PROC antes de acabar el anterior,\hfil\break
  3573.   $\bullet$ no anidas los bucles correctamente, por ejemplo:\hfil\break
  3574.   \null\qquad\qquad|FOR|\hfil\break
  3575.   \null\qquad\qquad|  IF|\hfil\break
  3576.   \null\qquad\qquad|  ENDFOR|\hfil\break
  3577.   \null\qquad\qquad|ENDIF|
  3578. \error 'illegal command-line option'
  3579.   'opci\'on de l\'{\i}nea de comandos ilegal'
  3580.   Al especificar |'EC -opt fuente'| escribiste algo para |-opt|  que no es
  3581.   una opci\'on legal de~|EC|.
  3582. \error 'division and multiplication 16bit only'
  3583.   'divisi\'on y multiplicaci\'on s\'olo con 16 bits'
  3584.   El compilador detect\'o que  estabas a punto de usar 32 bits  para |*| o |/|.
  3585.   Lo cual no tendr\'{\i}a el resultado deseado en tiempo de ejecuci\'on.
  3586. \error 'superfluous items in expression/statement'
  3587.   'elementos superfluos en expresi\'on/sentencia'
  3588.   Despu\'es de  haber compilado  tu sentencia,  el compilador  a\'un encontr\'o
  3589.   tokens l\'exicos  en vez del  final de l\'{\i}nea.  Es probable que  te hallas
  3590.   olvidado del \<|lf|> o ``|;|'' para separar dos sentencias.
  3591. \error 'procedure |"main"| not available'
  3592.   'no se dispone del procedimiento |"main"|'
  3593.   !`Tu programa no incluye un procedimiento |main()|!
  3594. \error 'double declaration of label'
  3595.   'doble declaraci\'on de una etiqueta'
  3596.   Declaraste una etiqueta dos veces, por ejemplo:\qquad|etiqueta:|\quad y\quad|PROC etiqueta()|
  3597. \error 'unsafe use of |"*"| or |"/"|'
  3598.   'uso de |"*"| o  |"/"| no seguro'
  3599.   De nuevo relacionado con el hecho de que los operadores |*| y |/| son de 16 bits, y no de 32.
  3600.   Mira 'divisi\'on y multiplicaci\'on s\'olo con 16 bits'.
  3601. \error 'reading sourcefile didn{'}t succeed'
  3602.   'sin \'exito al leer el fichero fuente'
  3603.   Comprueba  la  especificaci\'on de  fichero  fuente  que diste  con |ec mifuente|,
  3604.   aseg\'urate de que acaba en |.e|\nota{en la versi\'on actual del compilador
  3605.   ya no es necesario poner la extensi\'on.}
  3606. \error 'writing executable didn{'}t succeed'
  3607.   'sin exito al escribir el ejecutable'
  3608.   Al escribir el c\'odigo generado como ejecutable produjo un error de DOS\null{}.
  3609.   Por ejemplo, el ejecutable que ya exist\'{\i}a no se pudo reescribir.
  3610. \error 'no args'
  3611.   'faltan argumentos'
  3612.   |USAGE: ec [-opts] <sourcecodefilename> (`.e' is added)|\hfil\break
  3613.   |USO: ec [-opts] <nombrefichfuente> (se a\~nade `.e')|\hfil\break
  3614.   Obtienes esto simplemente con escribir |ec| sin ning\'un argumento.
  3615. \error 'unknown/illegal addressing mode'
  3616.   'modo de direccionamiento desconocido/ilegal'
  3617.   Este error s\'olo es del ensamblador en l\'{\i}nea.  Las posibles causas son:\hfil\break
  3618.   $\bullet$ usaste alg\'un tipo de direccionamiento que no existe en el 68000\hfil\break
  3619.   $\bullet$ el modo de direccionamiento existe, pero no para esa instrucci\'on.  No
  3620.     todas  las instrucci\'ones  en ensamblador  permiten todas las combinaciones
  3621.     de direcci\'on efectiva tanto para origen como destino.
  3622. \error 'unmatched parentheses'
  3623.   'discordancia de par\'entesis'
  3624.   Tu sentencia tienen m\'as ``|(|'' que ``|)|'' o la rev\'es.
  3625. \error 'double declaration'
  3626.   'declaraci\'on doble'
  3627.   Un identificador se usa en dos o m\'as declaraciones.
  3628. \error 'unknown identifier'
  3629.   'identificador desconocido'
  3630.   Un  identificador  no  se  usa  en ninguna declaraci\'on; es desconocido.
  3631.   Probablemente te olvidaste de ponerlo en una sentencia |DEF|.
  3632. \error 'incorrect \#of args or use of |()|'
  3633.   'n\'umero de args o uso de |()| incorrecto'
  3634.   $\bullet$ Te olvidaste poner ``|(|'' o ``|)|'' en el punto correcto,\hfil\break
  3635.   $\bullet$ pasate un n\'umero de argumentos incorrecto a alguna funci\'on.
  3636. \error 'unknown e/library function'
  3637.   'funci\'on de E/de biblioteca desconocida'
  3638.   Utilizas un identificador con el primer caracter en may\'uscula y segundo
  3639.   en min\'uscula, pero el compilador no le encontr\'o ninguna definici\'on.
  3640.   Posibles causas:\hfil\break
  3641.   $\bullet$ Nombre de funci\'on m\'al escrito.\hfil\break
  3642.   $\bullet$ Se te olvid\'o incluir el m\'odulo que define esa llamada.
  3643. \error 'illegal function call'
  3644.   'llamada ilegal a funci\'on'
  3645.   Raramente aparece.  Puede aparecer  si intentas  construir  llamadas  a
  3646.   extra\~nas, como |WriteF()|s anidados. \ Ejemplo:\qquad|WriteF(WriteF('!`hola!'))|
  3647. \error 'unknown format code following $\backslash$'
  3648.   'c\'odigo de formato que sigue a $\backslash$ desconocido'
  3649.   Especificaste un c\'odigo de formato ilegal en una cadena.
  3650. \error '|/*| not properly nested comment structure |*/|'
  3651.   '|/*| estrutura de comentarios incorrectamente anidada |*/|'
  3652.   N\'umero de |/*| no es igual al de |*/|, o est\'an en orden inapropiado.
  3653. \error 'could not load binary'
  3654.   'no he podido leer binario'
  3655.   No se pudo leer \<especfichero> en |INCBIN |\<especfichero>.
  3656. \error '|"|$\}$|"| expected'
  3657.   'se esperaba |"|$\}$|"|'
  3658.   Empezaste una expresi\'on con |{|\<var>, pero se te olvid\'o el |}| final.
  3659. \error 'immediate value expected'
  3660.   'se esperaba un valor inmediato'
  3661.   Algunas construcciones  requieren un  valor inmediato  en lugar  de una
  3662.   expresi\'on.  Por ejemplo:\hfil\break
  3663.   \null\qquad\qquad|DEF s[x*y]:STRING  -> mal: s\'olo es legal algo como s[100]:STRING|
  3664. \error 'incorrect size of value'
  3665.   'tama\~no de valor incorrecto'
  3666.   Especificaste un valor inaceptablemente  grande (o peque\~no) para alguna
  3667.   construcci\'on.  Ejemplos:\hfil\break
  3668.   \null\qquad\qquad|DEF s[-1]:STRING, t[1000000]:STRING    /* debe ser 0..32000  */|\hfil\break
  3669.   \null\qquad\qquad|MOVEQ #1000,D2                         /* debe ser -128..127 */|
  3670. \error 'no e code allowed in assembly modus'
  3671.   'no se permite c\'odigo E en modo ensamblador'
  3672.   Pusiste  el compilador  en modo  ensamblador con |OPT ASM|,  pero  por
  3673.   accidente escribiste algo de c\'odigo en~E.
  3674. \error 'illegal/inappropriate type'
  3675.   'tipo ilegal/no apropiado'
  3676.   En alg\'un lugar donde se necesitaba una especificaci\'on \<tipo> escribiste
  3677.   algo no apropiado.  Ejemplos:\hfil\break
  3678.   \null\qquad\qquad|DEF a:PTR TO ARRAY       /* no hay tal tipo */|\hfil\break
  3679.   \null\qquad\qquad|[1,2,3]:STRING|
  3680. \error '|"]"| expected'
  3681.   'esperaba |"]"|'
  3682.   Empezaste con |[| pero nunca lo acabaste con |]|.
  3683. \error 'statement out of local/global scope'
  3684.   'sentencia fuera del alcance local/global'
  3685.   Un punto de  ruptura del alcance es la primera sentencia |PROC|\null{}.  Antes de
  3686.   ella s\'olo se permiten definiciones globales (|DEF|,|CONST|,|MODULE|,etc.), no
  3687.   c\'odigo.  En la segunda parte s\'olo son legales c\'odigo  y definiciones de
  3688.   funciones, no definiciones globales.
  3689. \error 'could not read module correctly'
  3690.   'no se pudo leer el m\'odulo correctamente'
  3691.   Ocurri\'o un error DOS intentando leer un m\'odulo en una sentencia |MODULE|\null{}.
  3692.   Causas:\hfil\break
  3693.   $\bullet$ |EModules:| no ha sido asignado correctamente.\hfil\break
  3694.   $\bullet$ Nombre del m\'odulo escrito de forma incorrecta, o no existe.\hfil\break
  3695.   $\bullet$ Escribiste |MODULE 'bla.m'| en lugar de |MODULE 'bla'|.
  3696. \error 'workspace full!'
  3697.   '!`espacio de trabajo lleno!'
  3698.   Raras veces aparece.  Si lo hace,  deber\'as usar la opci\'on ``|-m|'' (|ADDBUF|)
  3699.   para forzar a~|EC|  a que haga una estimaci\'on superior de la cantidad  de
  3700.   memoria que necesita.  Intenta compilar  con  |-m2|,  luego con  |-m3|,~\dots,
  3701.   hasta que desaparezca el error.  Es probable que hayas escrito una
  3702.   aplicaci\'on enorme con cantidades de datos gigantes antes de poder tener la
  3703.   oportunidad de obtener este error.
  3704. \error 'not enough memory while (re-)allocating'
  3705.   'memoria no suficiente al (re-)reservar'
  3706.   Simplemente eso.  Posibles soluciones:\hfil\break
  3707.   |1. |Estabas  corriendo  otros  programas  en  multitarea.  Aband\'onalos  e
  3708.      intentalo de nuevo.\hfil\break
  3709.   |2. |Ten\'{\i}as,  poca  memoria  y  tu  memoria  estaba
  3710.      fragmentada.  Prueba reiniciando el sistema.\hfil\break
  3711.   |3. |Ninguna de |1-2|.  Compra una expansi\'on de memoria (ejem!).
  3712. \error 'incorrect object definition'
  3713.   'definci\'on de objeto incorrecta'
  3714.   Escribiste alguna torpeza en las definiciones entre |OBJECT| y |ENDOBJECT|.
  3715. \error 'illegal use of/reference to object'
  3716.   'uso ilegal de/referencia a objeto'
  3717.   Si usas expresiones como |ptr.miembro|, |miembro| debe ser un miembro legal
  3718.   del objeto al que apunta |ptr|.
  3719. \error 'incomplete |IF THEN ELSE| expression'
  3720.   'expresi\'on |IF THEN ELSE| incompleta'
  3721.   Si usas |IF| como operador, la parte |ELSE| es imprescindible: una expresi\'on
  3722.   con un |IF| en ella siempre necesita retornar un valor,  mientras que una
  3723.   sentencia con un  |IF|  en ella puede,  simplemente,  no hacer nada si no
  3724.   est\'a presente una parte |ELSE|.
  3725. \error 'unknown object identifier'
  3726.   'identificador de objeto desconocido'
  3727.   Usaste  un identificador  reconocido por  el compilador  como parte  de
  3728.   alg\'un objeto, pero se te olvid\'o declararlo.  Motivos:\hfil\break
  3729.   $\bullet$ nombre mal escrito\hfil\break
  3730.   $\bullet$ falta el m\'odulo\hfil\break
  3731.   $\bullet$ el identificador del m\'odulo no se escribe como esperas  de los RKRMs.
  3732.     Compruebalo con |ShowModule|.  Tienes que tener en cuenta que el sistema
  3733.     de objetos del Amiga  se hereda de  los identificadores del ensamblador,
  3734.     no del~C\null{}.  Y adem\'as siguen la sintaxis de~E.
  3735. \error 'double declaration of object identifier'
  3736.   'redeclaraci\'on de identificador de objeto'
  3737.   Se usa un mismo identificador en la definici\'on de dos objetos.
  3738. \error 'reference(s) out of 32k range: switch to |LARGE| model'
  3739.   'referencia(s) fuera del rango de 32k: cambia a modelo |LARGE|'
  3740.   S\'olo tienes que poner |OPT LARGE| en tu c\'odigo fuente y seguir.
  3741. \error 'reference(s) out of 256 byte range'
  3742.   'referencia(s) fuera del rango de 256 bytes'
  3743.   Es probable que hayas escrito un |BRA.S| o |Bcc.S| a gran distancia.
  3744. \error 'too sizy expression'
  3745.   'expresi\'on muy grande'
  3746.   Usaste cadenas |''| o listas |[]|, quizas |[[]]| recursivas, de gran tama\~no.
  3747. \error 'incomplete exception handler definition'
  3748.   'definici\'on de manejador de excepciones incompleto'
  3749.   Probablemente usaste |EXCEPT| sin |HANDLE|, o al rev\'es.
  3750. \error 'not allowed in a module'
  3751.   'no permitido en un m\'odulo'
  3752.   Estas haciendo  una de  las pocas cosas  que no se  pueden hacer  en un
  3753.   m\'odulo, como son variables globales con inicializaci\'on.
  3754. \error 'allowed in modules only'
  3755.   's\'olo se permite en m\'odulos'
  3756.   Es probable que hayas usado |EXPORT| en tu c\'odigo fuente principal.
  3757. \error 'this doesn{'}t make sense'
  3758.   'esto no tiene sentido'
  3759.   Error general.
  3760. \error 'you need a newer version of |EC| for this |:-)|'
  3761.   'necesitas una versi\'on m\'as reciente de |EC| para esto |:-)|'
  3762.   Es  probable que  estes  usando un  m\'odulo que  fue  compilado con  una
  3763.   versi\'on m\'as reciente de la que tienes.
  3764. \error 'no matching |"["|'
  3765.   '|"["| sin emparejar'
  3766.   Se encontr\'o un |]| en una sentencia sin un |[| que lo empareja.
  3767. \error 'this instruction needs a better |CPU/FPU| (see |OPT|)'
  3768.   'esta instrucci\'on necesita una |CPU/FPU| mejor (mira |OPT|)'
  3769.   Usas  una  construcci\'on  (probablemente  una  instrucci\'on en ensamblador)  que
  3770.   requiere un |OPT 020| o parecido.
  3771. \error 'object doesn{'}t understand this method'
  3772.   'el objeto no entiende este m\'etodo'
  3773.   Invocaste un m\'etodo que no fu\'e definido para ese objeto.
  3774. \error 'method doesn{'}t have same \#of args as method of baseclass'
  3775.   'el m\'etodo no tiene el mismo n\'umero de args que el de la clase base'
  3776.   Si redefines  un m\'etodo,  debes asegurarte  de que  el nuevo  tiene el
  3777.   mismo n\'umero de argumentos que el original.
  3778. \error 'too many register variables in this function'
  3779.   'demasiadas variables registro en esta funci\'on'
  3780.   Estas declarando variables resgitro con |:REG|, y de momemto
  3781.   no se pueden usar m\'as de |5|.
  3782. \error 'Linker can{'}t find all symbols'
  3783.   'el enlazador no encuentra todos los s\'{\i}mbolos'
  3784.   Si usas un  m\'odulo $A$ que usa a  su vez un m\'odulo $B$,  $B$ tambi\'en debe ser
  3785.   enlazado.  $A$ depende  de ciertos  |PROC|s  que estan  en  $B$,  y si $B$  fue
  3786.   recompilado sin esos  |PROC|s,  entonces el enlazador tendr\'a problemas al
  3787.   crear tu ejecutable.
  3788. \error 'could not open |"mathieeesingbas.library"|'
  3789.   'no pude abrir |"mathieeesingbas.library"|'
  3790.   Si usas c\'odigo con reales, el propio compilador necesitar\'a funciones de
  3791.   reales para poder generar el c\'odigo.
  3792. \error 'illegal destructor definition'
  3793.   'definici\'on de desctructor ilegal'
  3794.   Definiste un m\'etodo |end()| con argumentos (o con valor de retorno).
  3795. \error 'implicit initialisation of private members'
  3796.   'inicializaci\'on impl\'{\i}cita de miembros privados'
  3797.   Escribiste una expresi\'on |[...]| o |NEW [...]| que tiene partes privadas.
  3798. \error 'double method declaration'
  3799.   'redefinici\'on de m\'etodo'
  3800.   Definiste un m\'etodo dos veces para el mismo objeto.
  3801. \error 'object referenced by other object not found'
  3802.   'objeto hace referencia a otro que no se encuentra'
  3803.   Es probable  que heredaras de  alg\'un otro objeto  en otro m\'odulo,  y lo
  3804.   cambiaste  (por ejemplo  su  nombre) sin  cambiar\b/recompilar los  dem\'as
  3805.   m\'odulos que dependen de \'el tambi\'en.
  3806. \error 'unknown preprocessor keyword'
  3807.   'palabra clave de preprocesador desconocida'
  3808.   El preprocesador de |EC| s\'olo reconoce |#define|, |#ifdef|, |#ifndef| y |#endif|.
  3809. \error 'illegal macro definition'
  3810.   'definici\'on de macro ilegal'
  3811.   Provocaste un error de sintaxis al escribir tu |#define|.
  3812. \error 'incoherent \#|ifdef|/\#|ifndef| nesting'
  3813.   'anidamiento de \#|ifdef|/\#|ifndef| no coherente'
  3814.   Se te olvid\'o cerrar con |#endif|, o algo parecido.
  3815. \error 'macro redefinition'
  3816.   'redefinici\'on de macro'
  3817.   No puedes usar el mismo identificador de nombre de macro dos veces.
  3818. \error 'Sintaxis error in \#|ifdef|/\#|ifndef|/\#|else|/\#|endif|'
  3819.   'error de sintaxis en \#|ifdef|/\#|ifndef|/\#|else|/\#|endif|'
  3820.   ({\it mira el apartado sobre la correcta compilaci\'on de c\'odigo condicional\/}).
  3821. \error 'macro(s) nested too deep'
  3822.   'macro(s) anidada(s) a un nivel muy profundo'
  3823.   Obtendr\'as esto si tienes macros que  se expanden a otras, las cuales se
  3824.   expanden a otras,~\dots,  de forma que  la cantidad de  memoria necesaria
  3825.   para esto se empieza a desmadrar.  Lo m\'as seguro es  que hayas definido
  3826.   una macro recursiva (que intentar\'a expandirse indefinidamente).
  3827. \error 'method definition out of object/module scope'
  3828.   'definci\'on de m\'etodo fuera del alcance del objeto/m\'odulo'
  3829.   S\'olo puedes definir m\'etodos para un objeto en el mismo m\'odulo\b/fuente en
  3830.   el que se define el objeto.
  3831. \parindent=2em
  3832. \seccion Organizaci\'on del buffer del compilador y reserva.
  3833. Es \'util saber  como organiza |EC| sus buffers,  cuando obtienes un error
  3834. de {\ninebf 'workspace full'} (raras veces),  o quieres saber qu\'e  es lo que sucede
  3835. realmente cuando se compila tu programa.
  3836. \espacio
  3837.    Un compilador, y en este caso  |EC|, necesita buffers para mantener todo
  3838. tipo de cosas,  como identificadores, etc~\dots,  y necesita  un buffer para
  3839. almacenar  el c\'odigo que genera.  |EC|  desconoce el tama\~no que deben tener
  3840. esos buffers.  Esto no representa ning\'un problema para  la mayor\'{\i}a de los
  3841. buffers, como el que se utiliza para varias estructuras,  si el buffer se
  3842. llena durante la compilaci\'on,  |EC| s\'olo tiene que reservar  un nuevo fragmento
  3843. de memoria y continuar.  Sin embargo,  otros buffers,  como  el que
  3844. contiene el c\'odigo  generado, debe estar en un bloque de memoria cont\'{\i}guo
  3845. que no cambien durante la compilaci\'on: |EC| necista hacer una buena estimaci\'on
  3846. sobre el tama\~no de este buffer para poder compilar c\'odigo fuente  ya
  3847. sea grande o peque\~no.  Para ello  |EC|  calcula  la memoria  que necesitar\'a
  3848. dependiendo  del  tama\~no  del  c\'odigo  fuente,  y  le suma  una  cantidad
  3849. apropiada.  De esta forma,  en el  99\%~de los casos,  |EC|  habr\'a reservado
  3850. suficiente memoria  para compilar practicamente cualquier  c\'odigo fuente,
  3851. en los dem\'as casos, se te ofrecer\'a un error y tendr\'as que especificar m\'as
  3852. memoria con la opci\'on |-m| (|ADDBUF|).
  3853. \espacio
  3854.    Para ver c\'omo funciona esto en la pr\'actica prueba con fuentes de diferentes
  3855. tipos y tama\~nos en combinaci\'on con la opci\'on |-b| (|SHOWBUF|).
  3856. \seccion Reserva de registros.
  3857. E v3 permite la reserva de registros, que es una t\'ecnica para mantener
  3858. variables en  registros en  lugar de  la pila.  En c\'odigo normal  que use
  3859. rutinas del~SO  no  notar\'as mucho la  diferencia,  aunque para  bucles de
  3860. computaci\'on peque\~nos, esta optimizaci\'on puede marcar una gran diferencia.
  3861. \espacio
  3862. Hay dos formas de utilizar reserva de registros:
  3863. \item{$-$} Con la opci\'on |REG|.
  3864. \item{} Si,  por ejemplo,  escribes  |EC REG=3 bla.e|,  (de momento max=5),  |EC|
  3865.   buscar\'a para  cada |PROC| las tres  variables m\'as usadas y  las pondr\'a en
  3866.   registros.  La resreva  de  registro  es una  t\'ecnica  que intenta  ser
  3867.   inteligente: calcular\'a un peso para cada variable,  y usar\'a heur\'{\i}sticos
  3868.   para incrementar tal peso, por ejemplo, una variable usada en un bucle
  3869.   |FOR| obtiene  un peso relativamente mayor  que una usada fuera de \'el,  y
  3870.   una en un  |IF| obtendr\'a un peso incluso menor.  Estos pesos se combinan,
  3871.   de forma que un |WHILE| en un |FOR| obtiene un peso bastante mayor.
  3872. \item{$-$} HTM (Hazlo Tu Mismo).
  3873. \item{}  Puedes poner  la palabra  clave |REG|  delante de  cualquier tipo  en una
  3874.   declaraci\'on, por ejemplo:
  3875. \itemitem{} |DEF x:REG, s[4]:REG LIST|
  3876. \item{}  puedes utilizarlo si no crees en el reservador de registros, o si quieres
  3877.   realizar un ajuste fino en un s\'olo |PROC|\null{}.  Incluso  puedes  usar las
  3878.   dos t\'ecnicas juntas:  si en un |PROC| tienes una variable con |:REG|, compilar
  3879.   con |REG=5| permitir\'a a~|EC| repartir los 4~restantes por s\'{\i} mismo.
  3880. \Espacio
  3881. Por omisi\'on |REG=0|, haciendo que |EC| opere como en versiones anteriores.
  3882. \espacio
  3883. S\'olo  se {\bf pueden}  reservar  variables locales  que  no son  par\'ametros.
  3884. Ademas, si tomas la direcci\'on de una  variable con |{}|, no la puedes poner
  3885. en un  registro (adivina  por qu\'e).  No se  pueden reservar  registros en
  3886. |PROC|s que tienen manejador de excepciones, de momento.
  3887. \Espacio
  3888. Estas son algunas cosas a tener en cuenta al usar registros:
  3889. \item{$-$} Esta parte de |EC| (E v3.0a)  se ha comprobado ser bastante fiable,  pero
  3890.   debes seguir comprobando que el funcionamiento sea igual que  en c\'odigo
  3891.   sin reserva.
  3892. \item{}  {\sl Debe} funcionar bien, pero es demasiado pronto para garantizarlo |:-)|
  3893.   Resumiendo: desde este momento, ten cuidado al aplicar estas t\'ecnicas.
  3894. \item{$-$} |EC| usa  los  registros  |D7...D3|  para  variables,  de modo  que si usas
  3895.   ensamblador en l\'{\i}nea,  debes procurar que los |PROC|s que usan reserva de
  3896.   registros  o  |:REG|  no  los  ensucien.   El c\'odigo generado por un |PROC|
  3897.   guarda  de  forma  autom\'atica  los  registros  que usa para proteger el
  3898.   c\'odigo desde el que fu\'e llamado.
  3899. \item{$-$} Pista:  compilar con |REG=5|  no tiene porqu\'e ser m\'as r\'apido,  ya  que el
  3900.   guardar las variables en llamadas a funci\'on\b/librer\'{\i}a implica m\'as c\'odigo
  3901.   a ejecutar.  Adem\'as, si {\it todo} el c\'odigo en cuesti\'on opera con llamadas
  3902.   de librer\'{\i}a  en lugar de  computaci\'on pura, no esperes  ninguna ventaja
  3903.   con los registros.
  3904. \begintt
  3905. PROC main()                -> este programa sera dos veces mas rapido
  3906.   DEF a,b=10,c=20,d        -> facilmente si se reservan registros.
  3907.   FOR a:=1 TO 1000000 DO d:=b+c
  3908. ENDPROC
  3909. PROC main()                -> este sera, como mucho, un 5% mas rapido
  3910.   DEF a,s[100]:STRING,t    -> reservando registros.
  3911.   t:='poner "a" en un reg no creo que acelere esto mucho.'
  3912.   FOR a:=1 TO 100000 DO StrCopy(s,t)
  3913. ENDPROC
  3914. \endtt
  3915. \endchapter\saltacap
  3916. \beginchapter Cap\'{\i}tulo 17. Utilidades\\imprescindibles
  3917. \seccion bin/showmodule.
  3918. Como ya habr\'as notado,  el equivalente de~E para los {\sl includes\/}\nota{ficheros de cabecera},
  3919. los m\'odulos,  son ficheros binarios,  muy parecidos a los que se  ofrecen con
  3920. los compiladores de Modula2 por ejemplo.  Para ver el  contenido de tales
  3921. ficheros en forma \ASCII/ legible,  puedes utilizar |ShowModule|:
  3922. \ejemplos
  3923. &|ShowModule |\<especmodulo>\cr
  3924. \Ejemplos
  3925. Ejemplos:&|1> showmodule EModules:intuition/intuition|\cr
  3926.          &|1> showmodule >gadtools.txt EModules:gadtools|\cr
  3927. Por omisi\'on  |ShowModule|  escribe  a |stdout|,  y  se  puede
  3928. detener en cualquier momento con \<|CtrlC|>.
  3929. \seccion sources/utilities/showhunk{.}e, bin/showhunk.
  3930. Muestra  todo  tipo  de   ficheros  ejecutables,  adem\'as  de  ficheros
  3931. objeto |.o| generados por (otros) compiladores\b/ensambladores.  Muestra la
  3932. estructura  (muy simple)  de  los ejecutables  generados  por~|EC|,  aunque
  3933. tambien permite ficheros overlay complejos. Tambi\'en muestra las etiquetas
  3934. (como |XREF|s y |XDEF|s).  Y lo  m\'as importante de todo,  |ShowHunk| ofrece
  3935. un  desensamblador para los bloques de c\'odigo, usando la opci\'on |DISASM/S|.
  3936. \ejemplos
  3937. &|ShowHunk |\<ficheroeje>\cr
  3938. \Ejemplos
  3939. Ejemplos:&|1> ShowHunk holamundo|\cr
  3940.          &|1> ShowHunk DISASM dpaint|\cr
  3941. \seccion bin/iconvert, bin/pragma2module.
  3942. Estas  dos utilidades  son  s\'olo para  programadores  de~E avanzados\nota{al igual
  3943.  que la utilidad |ShowModule|,  ya  no  se incluye el c\'odigo
  3944.  fuente de estas utilidades en la distribuci\'on, ya que la gente utilizaba
  3945.  de forma incorrecta  su conocimiento  del  formato  de los m\'odulos |.m|.
  3946.  Es {\bf privado}.  Contacta conmigo primero si quieres hacer algo con \'el.}.
  3947. S\'altate este apartado si crees que (todav\'{\i}a) no eres uno de ellos.
  3948. \espacio
  3949. |IConvert|  convierte definiciones  de estructuras  y constantes  de los
  3950. ficheros |.i| en ensamblador a m\'odulos~E,  y |Pragma2Module|  hace lo mismo
  3951. con ficheros |pragma| de SAS/C de definici\'on de librer\'{\i}a.  Por supuesto, ya
  3952. se han  convertido de esta  forma todos  los includes de Commodore,  pero
  3953. digamos que  encuentras una librer\'{\i}a  de PD que  te gustar\'{\i}a usar  con~E,
  3954. entonces necesitar\'as estas utilidades.
  3955. \espacio
  3956.    La mayor\'{\i}a  de las  librer\'{\i}as vienen  con varios  includes definiendo,
  3957. obviamente, las llamadas  a librer\'{\i}a de la librer\'{\i}a,  as\'{\i} como constantes
  3958. y  estructuras  (|OBJECT|os  en~E)  que  utiliza.  Digamos  que  se  llama
  3959. |tools.library|, entonces, es probable que incluya:
  3960. \ejemplos
  3961. &|pragmas/tools_pragmas.h|\cr
  3962. &|includes/tools.i|\cr
  3963. entonces tienes que hacer:
  3964. \ejemplos
  3965. &|1> Pragma2Module tools_pragmas.h|\cr
  3966. renombrar el   |tools_pragmas.m|  resultante  a  |tools.m|   y  ponerlo  en
  3967. |EModules:|, luego comprueba con |ShowModule| si todo fue correcto.  Despu\'es de esto
  3968. ya puedes usar la |tools.library| en tu programa:
  3969. \ejemplos
  3970. &|MODULE 'tools'|\cr
  3971. \Esptab
  3972. &|PROC main()|\cr
  3973. &|  IF (toolsbase:=Openlibrary('tools.library',37))=NIL THEN error()|\cr
  3974. &|....|\cr
  3975. &|  ToolsFunc()|\cr
  3976. &|....|\cr
  3977. \finsma
  3978. Ahora con |IConvert| convierte  |tools.i| a |tools.m|,  el cual  puedes
  3979. colocar  en el directorio |EModules/libraries/|.  |IConvert|  necesita  un
  3980. ensamblador como el A68k  de DP para hacer la mayor  parte del trabajo de
  3981. traducci\'on del ensamblador.
  3982. \Ejemplos
  3983. &|1> IConvert tools.i|\cr
  3984. mira con  |ShowModule|  todo lo que se obtuvo del fichero |.i|.  Y  ya lo  podr\'as
  3985. usar en tu programa con:
  3986. \ejemplos
  3987. &|MODULE 'libraries/tools'|\cr
  3988. \Esptab
  3989. &|DEF x:toolsobj, y=TOOLS_CONST|\cr
  3990. \finsma
  3991. La  conversi\'on  con  |IConvert|  puede requerir  alguna  experiencia  con
  3992. ensamblador,  ya que |IConvert|  depende del  formato correcto  del fichero
  3993. |.i|, justo como los includes de ensamblador de  Commodore.  Es necesario
  3994. corregir amano cerca del 10\% de los ficheros |.i| para poder {\it convertirlos}.
  3995. Las expresiones que |IConvert| piensa que son correctas son, entre otras:
  3996. \ejemplos
  3997. &\<etiqueta>| EQU |\<expresi\'on\_cualquiera>\cr
  3998. \Esptab
  3999. &|STRUCTURE |\<nombreEs>|,0  ; |si |<>0,| entonces \<estructura>|_SIZEOF|\cr
  4000. &|ULONG |\<nombreEs>|_|\<etiqueta>\cr
  4001. &|BPTR |\<nombreEs>|_|\<etiqueta>\cr
  4002. &|  ; |etc.\cr
  4003. &|LABEL |\<nombreEs>|_SIZEOF  ; |o |"_SIZE"|\cr
  4004. \Espacio
  4005. Para tener una idea del tipo de expresiones en ensamblador con las que
  4006. puede  operar  |IConvert|,  hecha  un vistazo a los includes ensamblador de
  4007. Commodore y comp\'aralos con sus m\'odulos equivalentes (ej.~|intuition.i|).
  4008. \seccion bin/ShowCache, bin/FlushCache.
  4009. El  Cach\'e de  Modulos de E  es un  fragmento de  memoria que  permite
  4010. mantener m\'odulos  (|.m|) entre compilaciones.  La primera  vez que  usas un
  4011. cierto m\'odulo,  |EC|  lo leer\'a  del  disco y  lo  pondr\'a en  el cach\'e.  Las
  4012. siguientes veces |EC| lo encontrar\'a en el cach\'e,  y no tendr\'a que leer nada
  4013. de disco.  Si  |EC|  compila un m\'odulo del cual hay una versi\'on anterior en
  4014. el cach\'e lo sacar\'a del cach\'e.  Puedes imaginar que esto supone una mejora
  4015. en el tiempo de compilaci\'on enorme cuando se usan gran cantidad de m\'odulos
  4016. y se recompila a menudo, incluso para  gente con  disco duro,
  4017. \noin Para ver  qu\'e es  lo que  est\'a almacenado  en el  cach\'e en  un momento
  4018. determinado (y cuanta memoria se est\'a empleando |:-)|), teclea:
  4019. \ejemplos
  4020. &|1> ShowCache|\cr
  4021. \finsma
  4022. Una segunda utilidad,  |FlushCache|, permite eliminar selectivamente los
  4023. m\'odulos del cach\'e.  Las razones de esto pueden ser:
  4024. \item{$-$} No te puedes permitir prescindir de la memoria que utiliza,
  4025. \item{$-$} Creaste un nuevo |.m|,  con una herramienta distinta de |EC|,  por lo que
  4026.   nececitas vaciar el cach\'e a mano.
  4027. \espacio
  4028.    El argumento que recibe es la cadena que debe aparacer en el nombre de
  4029. un  m\'odulo para eliminarlo del cach\'e.  El no dar un argumento implica
  4030. el vaciado completo.
  4031. \ejemplos
  4032. &|1> FlushCache            ; vacia todo el cache|\cr
  4033. &|1> FlushCache intuition/ ; elimina modulos de intuition|\cr
  4034. \finsma
  4035. Puedes usar  la opci\'on de  |EC| |IGNORECACHE/S| para compilar  un fuente
  4036. sin usar el cach\'e.  Ya est\'e el cach\'e lleno o vac\'{\i}o,  |EC| lo  leer\'a todo de
  4037. disco,  y no pondr\'a nada en \'este.
  4038. \espacio
  4039. Si dos |EC|s intentan acceder al cach\'e simult\'aneamente en multitarea, el
  4040. segundo |EC| actuar\'a como si se le hubiera dado la opci\'on |IGNORECACHE|.
  4041. \seccion rexx/ecompile{.}rexx\nota{?`quien mantiene los otros scripts de ARexx?}.
  4042. Este es  un script  ARexx para  CygnusEd (tm),  y te  permite compilar
  4043. programas desde el editor.  Asigna este script a una tecla de
  4044. funci\'on en  el editor  con |Install Dos/Arexx Command ...|  (comprueba tu
  4045. manual de CED si no estas seguro de como hacer esto).  Ahora,  escribe tu
  4046. programa,  y pulsa  |Fx| si quieres compilar.  El c\'odigo fuente se guardar\'a
  4047. si  es  necesario, se  invocar\'a  al  compilador  en una  ventana  consola
  4048. separada,  y se ejecutar\'a el programa  en una ventana  consola diferente.
  4049. Cuando el programa acabe,  puedes pulsar  \<|return|>  para volver al editor
  4050. (el script realiza de forma  autom\'atica el cambio de la  pantalla de  CED
  4051. adelante y detr\'as).  Si ocurre un error durante la compilaci\'on, el script
  4052. permitir\'a a CED saltar a la l\'{\i}nea del error despu\'es de pulsar \<|return|>.
  4053. \espacio
  4054. (en  el script  hay un nombre  de camino que  indica donde  se puede
  4055. encontrar el compilador.  Es probable  que tengas que cambiarlo.  Adem\'as,
  4056. el  script copia |EC| a |RAM:|  para sistemas con un dispositivo |SYS:|  lento,
  4057. puede que quieras deshabilitar esto si tienes un disco duro r\'apido.)
  4058. \seccion bin/o2m.
  4059. Si tienes  bloques de  fuente en ensamblador  grandes que  te gustar\'{\i}a
  4060. usar,  ser\'{\i}a tedioso tener que,  como poco,  convertirlos todos a  mano a
  4061. ensamblador en  l\'{\i}nea de~E\null{}.  |o2m| te permite  hacer que, de forma sencilla, tu
  4062. macro-ensamblador  favorito te  lo ensamble  todo  a un  fichero |.o|,  y
  4063. entonces |o2m|  te convertir\'a ese fichero  |.o| a un fichero  |.m| para ser
  4064. usado con~E\null{}.  Si tienes un fichero |bla.o|:
  4065. \ejemplos
  4066. &|1> o2m bla|\cr
  4067. producir\'a |bla.m|.  Sin embargo,  el fichero |.o| tendr\'a que seguir ciertas
  4068. reglas.  Debe consistir  de un  s\'olo  bloque de  c\'odigo con  definiciones
  4069. externas (|XDEF|s)  para cada s\'{\i}mbolo al que desees  hacer referencia desde~E,
  4070. y ning\'un |XREF|\null{}.  Por lo general, tu fuente se parecer\'a a:
  4071. \ejemplos
  4072. &|        XDEF suma__ii|\cr
  4073. \Esptab
  4074. &|suma__ii:|\cr
  4075. &|        move.l  4(a7),d0|\cr
  4076. &|        add.l   8(a7),d0|\cr
  4077. &|        rts|\cr
  4078. un fragmento de ensamblador que recibe dos argumentos (de
  4079. ah\'{\i}  las  dos  ``|i|''  de  entero).  Los argumentos se encuentran en la
  4080. pila, donde |4(a7)| es el \'ultimo argumento, |8(a7)| el anterior,~\dots
  4081. \espacio
  4082. |ShowHunk| muestra esto como:
  4083. \ejemplos
  4084. &|        hunk_unit:|\cr
  4085. &|HUNK -1 hunk_name:|\cr
  4086. &|        hunk_code: 12 bytes|\cr
  4087. &|        hunk_ext|\cr
  4088. &|          add__ii = $0|\cr
  4089. este tipo de fichero |.o| se puede convertir facilmente a |.m| con |o2m|:
  4090. \ejemplos
  4091. &|/* this module contains 12 bytes of code! */|\cr
  4092. \Esptab
  4093. &|PROC add(a,b)|\cr
  4094. \finsma
  4095. Hay que destacar algunas cosas:
  4096. \item{$-$} si tu c\'odigo ensamblador usa |D3-D7/A4/A5| es probable que debas guardarlos.
  4097. \item{$-$} si una etiqueta  no tienen el  ``|__|'' con un  ``|i|''  para cada funci\'on,  se
  4098.   convierte  en una  funci\'on sin  par\'ametros.  No te preocupes  de si  la
  4099.   etiqueta  en  realidad  hace  referencia a  datos,  puedes  obtener  la
  4100.   direcci\'on de ese |PROC| con |{}|,  y usarla como un puntero a tus datos.
  4101. \espacio
  4102. En teor\'{\i}a, |o2m| se podr\'{\i}a usar para  enlazar c\'odigo~C a programas en~E,
  4103. sin  embargo,  a menudo,  en la  pr\'actica esto  no  es  factible.  Si  tu
  4104. compilador de~C te  permite {\sl ajustar} los  ficheros |.o|  resultantes un
  4105. poco, podr\'{\i}a funcionar. Aunque nos podemos encontrar con algunos problemas:
  4106. \item{$-$} referencia a funciones de C, por ejemplo |_printf()|.
  4107. \item{$-$} referencia a variables globales creadas por el c\'odigo de inicializaci\'on de~C\null{}.
  4108.   El c\'odigo en~C podr\'{\i}a  hacer referencia a |DOSBase| como |XREF|, mientras
  4109.   que  el c\'odigo inicializaci\'on de~E dispone este valor en alg\'un lugar de
  4110.   la pila.
  4111. \item{$-$} convenios de llamada/registros.
  4112. \noin Se pueden enlazar  con~E funciones de~C que s\'olo realicen
  4113. c\'alculos simples. (Yo he conseguido utilizarlas con \'exito usando
  4114. MaxonC++, cuyo enlazador usa el convenio |__ii| para los par\'ametros.)
  4115. \seccion bin/EYacc.
  4116. Esta es  una conversi\'on de  la famosa utilidad |Yacc| de Unix,  el cual
  4117. ahora produce c\'odigo~E en  lugar de c\'odigo~C\null{}.  Esta es s\'olo  una primera
  4118. versi\'on,  por  lo  que no esperes mucho de ella.  Si no tienes idea de lo
  4119. que  hace |Yacc|, lee alg\'un texto sobre ello (yo no voy a explicarlo aqu\'{\i}).
  4120. \espacio
  4121. B\'asicamente, puedes escribir ficheros |.y| como siempre,  s\'olo que donde
  4122. las acciones sol\'{\i}an escribirse en~C,  ahora puedes escribirlas en~E\null{}.
  4123. Mira el ejemplo |Src/Yacc/bcalc.y|.
  4124. \Ejemplos
  4125. &|1> eyacc bcalc.y|\cr
  4126. produce un fichero |yyparse.e|
  4127. \ejemplos
  4128. &|1> ec yyparse|\cr
  4129. genera un m\'odulo,  el cual s\'olo contiene la funci\'on  |yyparse()|.  El resto
  4130. del {\it como mediar con Yacc\/} debe ser an\'alogo al~C.
  4131. \espacio
  4132. ({\it tengo a medias una conversi\'on de Lex a E-Lex, aunque no acabada.}\/)
  4133. \Espacio
  4134. E-Yacc  es  una  modificaci\'on  del  Yacc 1.8 de Berkeley, de
  4135. |corbett@berkeley.edu|.   La  inclusi\'on  de  esta  versi\'on modificada en la
  4136. distribuci\'on  de~E es totalmente legal, ya que el autor dice en el |README|
  4137. original de BYacc1.8:
  4138. \espacio
  4139. {\sl ``Berkeley  Yacc is  in  the  public  domain.  The data  structures  and
  4140. algorithms  used in  Berkeley Yacc  are all  either taken  from documents
  4141. available to the  general public or are inventions of  the author. Anyone
  4142. may freely  distribute source  or binary forms  of Berkeley  Yacc whether
  4143. unchanged or  modified. Distributers  may charge  whatever fees  they can
  4144. obtain  for Berkeley  Yacc. Programs  generated by  Berkeley Yacc  may be
  4145. distributed freely.''}\nota{No veo ning\'un inter\'es en  realizar la traducci\'on de esto,
  4146. si no piensas igual, d\'{\i}melo:\hfil\break |u0868551@oboe.etsiig.uniovi.es|\qquad Antonio J. Gomez Glez.}
  4147. \seccion bin/SrcGen.
  4148. {\ninesl (Esta utilidad  no ha sido actualizada  para funcionar mejor con el
  4149.  sistema de m\'odulos de~E, todav\'{\i}a  genera el c\'odigo fuente llano (el cual
  4150.  se  incorpora  facilmente en cualquier  m\'odulo).  S\'olo la actualizar\'e si
  4151.  hay mucha demanda ello.  Si quieres incluir un GUI decente en tu aplicaci\'on
  4152.  echa un vistazo tambi\'en a {\ninett modules/tools/EasyGUI.m}, o a  kits  m\'as
  4153.  recientes como {\ninett BGUI} de Jan van den Baard, autor de GadToolBox.)}
  4154. \espacio
  4155. |SrcGen|, generador de fuente GadToolBox de para E: versi\'on beta
  4156. \espacio
  4157. Necesitar\'as GadToolBox v2.0 o superior, y tener la |gadtoolsbox.library|
  4158. que  viene  con  \'el en tu |LIBS:|.  Ahora, crea con GTB alg\'un ejemplo simple
  4159. (una  ventana  con unos pocos gadgets\b/menus etc.), gr\'abalo como |bla| (el
  4160. nombre del fichero ser\'a |bla.gui|), y teclea:
  4161. \ejemplos
  4162. &|1> SrcGen bla|\cr
  4163. &|1> EC bla|\cr
  4164. &|1> bla|\cr
  4165. \finsma
  4166. |bla.e| tendr\'a las rutinas de apertura de tu interface,  as\'{\i} como algunas
  4167. rutinas  para  manejar mensajes IDCMP, errores,~\dots, y un |main()| sencillo
  4168. que  s\'olamente  espera  por  una  selecci\'on.   Ah\'{\i} puedes poner tu propio
  4169. c\'odigo.   Mira  el  patr\'on de la l\'{\i}nea de comandos para ver como se evita
  4170. que |SrcGen| genere esas rutinas.
  4171. \espacio
  4172. Eso  es para  todo  lo  que sirve.  Si  tienes problemas,  simplemente
  4173. comprueba el c\'odigo que se gener\'o.
  4174. \seccion bin/EBuild.
  4175. |EBuild| es una copia de |Make|, y funciona de forma similar.  |EBuild| es
  4176. una  utilidad  que  te  ayuda  a  recompilar las partes necesarias de una
  4177. aplicaci\'on  grande  despu\'es de modificarla.  Escribes un fichero |.build|
  4178. en  el  directorio  que  contiene los fuentes de tu proyecto.  El fichero
  4179. contiene  informaci\'on  sobre  qu\'e  fuentes  dependen  de qu\'e otros, y qu\'e
  4180. acciones  se  deben llevar a cabo si es necesario reconstruir un m\'odulo o
  4181. un  ejecutable.   |EBuild| comprueba las fechas de los ficheros para ver si
  4182. se  ha  modificado  un fuente  despu\'es  de la \'utima compilaci\'on,  y si el
  4183. fuente  usa  m\'odulos  que tambi\'en  han sido modificados,  compilando esos
  4184. \'ultimos primero.
  4185. \espacio
  4186. La sintaxis es como la del make de Unix.  En resumen,  ``|#|'' precede
  4187. l\'{\i}neas con comentarios, y en:
  4188. \ejemplos
  4189. & |objetivo: dep1 dep2 ...|\cr
  4190. & |  accion1|\cr
  4191. & |  accion2|\cr
  4192. & |  ...|\cr
  4193. |objetivo| es el fichero resultado del  que estamos hablando, en la mayor\'{\i}a
  4194. de los casos un ejecutable o  un m\'odulo, aunque puede ser cualquier cosa.
  4195. Tras los  ``|:|''  puedes  escribir todos los ficheros  de  los que  depende,
  4196. probablemente su fuente, y otros m\'odulos.  Las acciones de las l\'{\i}neas que
  4197. le siguen son  comandos de AmigaDos normales,  y es necesario precederlos
  4198. de al menos un espacio o un tabulador para distinguirlas de objetivos.
  4199. \Ejemplos
  4200. & |bla: bla.e defs.m|\cr
  4201. & |     ec bla quiet|\cr
  4202. este sencillo ejemplo recompilar\'a |bla.e| si ha sido modificado,  o si
  4203. |defs.m| ha cambiado.
  4204. \espacio
  4205. Si  tecleas |EBuild|  sin argumentos,  |EBuild| se asegurar\'a  de que  el
  4206. primer objetivo est\'e actualizado.  Por otra parte, puedes darle las siguientes
  4207. opciones:
  4208. \ejemplos
  4209. &|TARGET,FROM/K,FORCE/S:|\cr
  4210. \finsma
  4211. Si das un |TARGET|\nota{objetivo},  |EBuild| empezar\'a con otro objetivo.  |FROM|
  4212. te permite usar otro fichero que no sea |.build|,  y  |FORCE|  reconstruir\'a
  4213. todo, independientemente de si era necesario o no.  Veamos un ejemplo:
  4214. \ejemplos
  4215. &|# fichero build de prueba|\cr
  4216. \Esptab
  4217. &|all:    bla burp|\cr
  4218. &|defs.m: defs.e|\cr
  4219. &|        ec defs quiet|\cr
  4220. &|bla:    bla.e defs.m|\cr
  4221. &|        ec bla quiet|\cr
  4222. &|burp:   burp.e|\cr
  4223. &|        ec burp quiet|\cr
  4224. &|limpia:|\cr
  4225. &|        delete defs.m bla burp|\cr
  4226. este fichero build es sobre dos programas, |bla| y |burp|,  de los cuales |bla|
  4227. tambi\'en depende de un m\'odulo |defs.m|.  Incorpora un objetivo extra no real
  4228. |limpia|  de forma que puedas escribir |EBuild limpia|  para borrar todos
  4229. los ficheros generados.
  4230. \espacio
  4231. Se pueden a\~nadir  otras  dependencias  y  acciones con facilidad.  Por
  4232. ejemplo, si tu proyecto usa un analizador generado por E-Yacc:
  4233. \begintt
  4234. yyparse.m: parser.y
  4235.            eyacc parser.y
  4236.            ec yyparse quiet
  4237. \endtt
  4238. \espacio
  4239. O  si incorpora c\'odigo de macro-ensamblador como m\'odulo de herramienta
  4240. usado a menudo:
  4241. \begintt
  4242. blerk.m: blerk.s
  4243.          a68k blerk.s
  4244.          o2m blerk
  4245.          copy blerk.m emodules:tools
  4246.          flushcache tools/blerk
  4247. \endtt
  4248. \espacio
  4249. En  el momento  en el que logres  conocer |EBuild|,  descubrir\'as que  lo
  4250. puedes  usar  para m\'as  prop\'ositos  a  parte  de \'este.  M\'{\i}ralo  como  una
  4251. herramienta de scripts inteligente.
  4252. \espacio
  4253. Si quieres descubrir  en detalle de lo que puede  hacer |EBuild|, lee la
  4254. documentaci\'on de alg\'un make de Unix,  ya que  |EBuild| es, de alguna forma,
  4255. compatible con \'el.  Lo que de momento no hace es:
  4256. \item{$-$} eliminar dependencias c\'{\i}clicas.
  4257. \item{$-$} permitir ``|\|'' al final de una l\'{\i}nea para reglas m\'as largas.
  4258. \item{$-$} definiciones constantes.
  4259. \espacio
  4260. Jason  Hulance  ha  actualizado  |EBuild|   para  la  versi\'on  v3.1  del
  4261. compilador  de~E,  para  corregir  el  error  que ejecutaba  acciones  en
  4262. orden inverso.  Tambi\'en  cambi\'o la  ejecuci\'on de  la acci\'on  a un  script
  4263. (transparente).  En ese script a la  variable |target| se le  da el valor
  4264. del objetivo actual.  Por ejemplo:
  4265. \begintt
  4266. test:   test.e
  4267.         ec "$target"
  4268.         if warn
  4269.                 echo "Error: fallo la compilacion"
  4270.         else
  4271.                 echo "Compilado OK... ejecutando"
  4272.                 "$target"
  4273.         endif
  4274. \endtt
  4275. que equivale al siguiente c\'odigo del |EBuild| antiguo, aunque permite m\'as cosas.
  4276. \begintt
  4277. all:    test
  4278.         echo "ok, ejecutando:"
  4279.         test
  4280. test:   test.e
  4281.         ec -q test
  4282. \endtt
  4283. \seccion EE / Aprof.
  4284. ({\ninesl Estos se describen en su propia documentaci\'on en el directorio {\ninett tools}.}\/)
  4285. \seccion EDBG.
  4286. |EDBG| es el depurador e nivel de  fuente de~E\null{}.  Para  usarlo
  4287. compila\nota{{\bf No} distribuyas un programa en el que alguna parte ha sido compilada
  4288. con  |DEBUG/S|  (puedes comprobarlo con  |ShowHunk|,  no debe contener ning\'un
  4289. |hunk_debug|).  Los programas con informaci\'on de depuraci\'on se compilan con
  4290. |NOP|s extra  para facilitar la  depuraci\'on, lo cual  no es deseable  en el
  4291. c\'odigo final.} tu fuente con la opci\'on |DEBUG| (esto funciona tanto para el
  4292. programa principal como para los m\'odulos), lo cual a\~nadir\'a informaci\'on de
  4293. depuraci\'on en tu ejecutable\b/m\'odulo.
  4294. \espacio
  4295. Aseg\'urate  siempre de  que tanto  el c\'odigo  fuente como  el compilado
  4296. est\'an en el directorio actual, entonces lanza |EDBG| con:
  4297. \ejemplos
  4298. &|1> EDBG nombreejecutable|\cr
  4299. \Ejemplos
  4300. patr\'on:&|EXECUTABLE/A,PUBSCREEN/K:|\cr
  4301. con |PUBSCREEN|  puedes  hacer que |EDBG| corra en cualquier lugar
  4302. (|PUBSCREEN=Workbench| para que funcione en el Workbench).  Por omisi\'on |EDBG|
  4303. abre  su  propia pantalla, la cual es una copia del Workbench en tama\~no y
  4304. modo de pantalla.  |EDBG| funciona bien en la tarjeta gr\'afica Picasso,~\dots
  4305. \noin |EDBG| abre una ventana para cada  fuente en tu proyecto, y empezar\'a con
  4306. el que contiene a |main()|.  Desde la  que puedes recorrer tu  c\'odigo, y se
  4307. abrir\'an ventanas autom\'aticamente cuando sean necesarias. Cuando el c\'odigo
  4308. no tiene  un fuente adjunto,  s\'olo se puede ejecutar  (lo cual es  \'util a
  4309. veces, si no es necesario depurarlo).
  4310. \noin Desde  ese  momento  todo  es  bastante  intuitivo.  Los  botones  m\'as
  4311. importantes son las dos primeras im\'agenes, que son el de {\sl recorre sobre/en}
  4312. ({\sl step over/in}\/).  Recorre en sigue el c\'odigo paso a paso seg\'un se ejecuta,
  4313. recorre sobre hace lo mismo pero no entra en las subrutinas.
  4314. (!`Pru\'ebalo!, el depurador es bastante intuitivo).
  4315. \noin Otras funciones sacan ventanas de memoria o registros, y algunas otras
  4316. funciones  (algunas sin implementar).  Una importante es  hacer un  doble
  4317. click  en nombres  de variables:  \'esto nos  mostrar\'a su  contenido en  la
  4318. ventana temporal (ya lo s\'e, esto ser\'a algo m\'as c\'omodo en el futuro).
  4319. \noin Pegas:
  4320. \item{$-$} El programa que se depura corre en la misma tarea que |EDBG|\null{}. Esto quiere
  4321.   decir que todo c\'odigo que haga cosas especiales en la tarea  deber\'a ser
  4322.   cuidadoso.  Un ejemplo es |Forbid()|.
  4323. \item{$-$} Un caso especial es |ReadArgs()|.  Dado que  |EDBG| ya ley\'o los argumentos,
  4324.   una  llamada del  programa  que se  depura causar\'a  una  lectura de  la
  4325.   consola. De forma que puedes teclear convenientemente los argumentos de
  4326.   tu programa en la l\'{\i}nea de comandos y pulsar \<|return|>.
  4327. \Espacio
  4328. |EDBG| todav\'{\i}a es algo beta, aunque ya bastante  \'util.  Le faltan gran
  4329. cantidad de funciones, y tendr\'as que esperar algo antes de que se lleguen
  4330. a implementar.  (por lo  tanto,  no  vengas a  contarme que ``{\sl X no
  4331. funciona}'' o que ``{\sl |EDBG| necesita X}'' porque  {\bf ya lo se}.)
  4332. \Espacio
  4333. \subsec Las opciones |LINEDEBUG| y |SYM|.
  4334. La  opci\'on |LINEDEBUG|  a\~nade  informaci\'on |linedebug|  a tu  ejecutable
  4335. (para cada l\'{\i}nea de c\'odigo dentro de un |PROC|)\null. |EDBG| necesita esta opci\'on,
  4336. aunque  la  opci\'on  |DEBUG|  la  activa  de forma autom\'atica.  |LINEDEBUG| es
  4337. parcialmente  compatible  con  el  |HUNK_DEBUG|  |"LINE"| producido por otros
  4338. compiladores\b/ensambladores,  por  lo que tambi\'en puede ser \'util con otras
  4339. herramientas  de  depuraci\'on.   La  opci\'on |SYM| no es necesaria para |EDBG|,
  4340. pero puede ser \'util para otros, como |AProf| o desensambladores.
  4341. \Espacio
  4342. \subsec Errores m\'as graves conocidos.
  4343. \item{$-$} no puedes  desplazar la l\'{\i}nea  actual fuera  de la parte visible en una
  4344.   ventana de fuente porque |EDBG| intenta mantenerla a la vista.
  4345. \item{$-$} muchos otros~\dots, probablemente
  4346. \seccion PreProcesador de |EC|.
  4347. |EC| tiene un preprocesador interno que ofrece substituciones de macros
  4348. y compilaci\'on condicional.  Estas no son caracter\'{\i}sticas  del lenguaje~E,
  4349. sino que se han integrado en |EC| por velocidad y flexibilidad.
  4350. \subsec Activando el preprocesador.
  4351. Hasta que no escribas:
  4352. \ejemplos
  4353. &|OPT PREPROCESS|\cr
  4354. |EC|  se comportar\'a  como siempre.  Esta  |OPT| es  necesaria para  cualquier
  4355. caracter\'{\i}stica relacionada con el preprocesador.
  4356. \subsec Macros.
  4357. El  macropreprocesador  es compatible con |Mac2E| y el prepocesador del~C\null{}.  Puedes
  4358. definir macros con:
  4359. \begintt
  4360. #define NOMBREMACRO
  4361. #define NOMBREMACRO CUERPO
  4362. #define NOMBREMACRO(ARG, ...) CUERPO
  4363. #define NOMBREMACRO(ARG, ...) CUERPO \
  4364.         RESTO DEL CUERPO
  4365. \endtt
  4366. |NOMBREMACRO| y |ARG| pueden tener tanto may\'usculas como min\'usculas, y pueden
  4367. contener |_|  y  |0-9|  como siempre.  Se pueden a\~nadir espacios en cualquier
  4368. lugar menos entre |NOMBREMACRO| y |(|,  ya que sino |EC| no podr\'{\i}a distinguir
  4369. entre argumentos y el cuerpo.
  4370. \noin El |CUERPO| puede contener cada uno  de los argumentos tantas veces como
  4371. quiera.  Una macro puede continuar en la l\'{\i}nea siguiente si se precede el
  4372. {\sl final-de-l\'{\i}nea}\/ con un |\|.  Una macro sin cuerpo puede ser \'util en
  4373. combinaci\'on con compilaci\'on condicional.
  4374. \espacio
  4375. Los identificadores de macro tienen precedencia sobre los dem\'as.
  4376. Las  macros  definidas en un m\'odulo s\'olo se guardan en el m\'odulo si se
  4377. activa  |OPT EXPORT| (|#define|  no  se puede preceder con |EXPORT|).  Si eso
  4378. representa  un  problema,  mant\'en  las macros juntas en su propio m\'odulo.
  4379. Las macros de los m\'odulos se pueden usar en c\'odigo diferente  simplemente
  4380. con importarlas con |MODULE|, y usando |OPT PREPROCESS|.
  4381. \subsec Usando una macro.
  4382. El uso  de |NOMBREMACRO| en cualquier  punto del  programa har\'a  que se
  4383. inserte el |CUERPO| de la macro en ese punto. Ten en cuenta que \'esta es una
  4384. substituci\'on de texto,  y tiene poco que ver con la sintaxis de~E en s\'{\i}.
  4385. Si las macros  tienen argumentos,  \'estos se insertar\'an en sus respectivos
  4386. lugares del cuerpo de la macro. Si el cuerpo (o los argumentos) contienen
  4387. m\'as macros, \'estos se expander\'an m\'as tarde.
  4388. \noin Ejemplo:
  4389. \begintt
  4390. #define MAX(x,y) (IF x>y THEN x ELSE y)
  4391. WriteF('el mayor = \d\n',MAX(10,a))
  4392. \endtt
  4393. es lo mismo que escribir:
  4394. \begintt
  4395. WriteF('el mayor = \d\n',(IF 10>a THEN 10 ELSE a))
  4396. \endtt
  4397. \espacio
  4398. Esto nos muestra el peligro de las macros:  escribir
  4399. |MAX(computacion_grande(),1)| generar\'a c\'odigo que ejecuta
  4400. |computacion_grande()| dos veces, ya que
  4401. simplemente se copia  textualmente.  Ten cuidado con eso.
  4402. \subsec Compilaci\'on condicional.
  4403. Esto puede ser \'util si quieres decidir en el momento de la compilaci\'on
  4404. qu\'e parte de tu c\'odigo quieres usar.  Veamos primero un ejemplo:
  4405. \begintt
  4406. #define DEPURA
  4407. ->#define DEPURABIEN
  4408. #ifdef DEPURA
  4409.   WriteF('entrando en bla() con x = \d\n',x)
  4410. #ifdef DEPURABIEN
  4411.   WriteF('volcando memoria...\n')
  4412.   /* ... */
  4413. #endif
  4414. #endif
  4415. \endtt
  4416. \Espacio
  4417. Su sintaxis es:
  4418. \ejemplos
  4419. & |#ifdef NOMBREMACRO|\cr
  4420. \ejemplos
  4421. & |#ifndef NOMBREMACRO|\cr
  4422. el fragmento de c\'odigo  que lo sigue se, o no se compilar\'a dependiendo de
  4423. si |NOMBREMACRO| fu\'e definido.  Puedes hacer esto simplemente con:
  4424. \ejemplos
  4425. & |#define MIBANDERA|\cr
  4426. o algo parecido.  Finaliza el bloque compilado condicionalmente con:
  4427. \ejemplos
  4428. & |#endif|\cr
  4429. adem\'as, este tipo de bloques se puede anidar como se vi
  4430.  en el ejemplo.
  4431. \endchapter\saltacap
  4432. \beginchapter Ap\'endice A. Correspondencia\\con otros\\lenguajes
  4433. \ninepoint
  4434. En este ap\'endice veremos una serie de tablas que tratan de mostrar la equivalencia
  4435. de diferentes elementos de E con otros lenguajes.
  4436. En las  dos primeras columnas  aparecer\'an las equivalencias entre E  y
  4437. AnsiC/C++, la  tercera columna  est\'a reservada  para un  tercer lenguaje.
  4438. La mayor parte de las veces usar\'e Pascal en esa  columna, aunque si una caracter\'{\i}stica
  4439. lo pide, usar\'e otros (LISP, por ejemplo, con expresiones entrecomilladas,
  4440. Ada con excepciones, etc~\dots)
  4441. \noin No te tomes muy en serio estas tablas, ya que cada lenguaje tiene sus peculiaridades.
  4442. \medskip
  4443. \halign to\hsize{\tt#\hfil\tabskip=2em plus30em minus1em& #\hfil& \tt#\hfil\tabskip=0pt\cr
  4444. \bartab
  4445. \multispan3\sc ESTRUCTURA/SENTENCIAS\hfil\cr
  4446. \sc E&                    \sc C/C++ &               \sc Pascal \cr
  4447. \bartab
  4448. PROC x() &               |int x() {| &              FUNCTION x: INTEGER; \cr
  4449. PROC x(y,z) &            |int x(y,z) {| &           FUNCTION x(y,z:INTEGER):INTEGER; \cr
  4450. PROC x(y=1) &            |int x(y=1) {| &           \rm -- \cr
  4451. ENDPROC &                |return 0; };| &           x:=0; END; \cr
  4452. ENDPROC e &              |return e; };| &           x:=e; END; \cr
  4453. ENDPROC e,f,g &          -- &                       \rm -- \cr
  4454. RETURN e &               |return e;| &              \rm ? \cr
  4455. \Esptab
  4456. IF e &                   |if(e) {| &                IF e THEN BEGIN \cr
  4457. ELSEIF e &               |} else if(e) {| &         END ELSE IF e THEN BEGIN \cr
  4458. ELSE &                   |} else {| &               END ELSE BEGIN \cr
  4459. ENDIF &                  |};| &                     END; \cr
  4460. IF e THEN s &            |if(e) s;| &               IF e THEN s; \cr
  4461. IF e THEN s ELSE t &     |if(e) s else t;| &        IF e THEN s ELSE t; \cr
  4462. \Esptab
  4463. FOR x:=e TO f &          --$^{(1)}$ &               FOR x:=e TO f DO BEGIN \cr
  4464. FOR x:=e TO f STEP i &   -- &                       \rm --$^{(2)}$ \cr
  4465. EXIT e &                 |if(e) break;| &           \rm -- \cr
  4466. ENDFOR &                 -- &                       END; \cr
  4467. FOR x:=e TO f DO s &     -- &                       FOR x:=e TO f DO s; \cr
  4468. \Esptab
  4469. WHILE e &                |while(e) {| &             WHILE e DO BEGIN \cr
  4470. EXIT e &                 |if(e) break;| &           \rm -- \cr
  4471. ENDWHILE &               |};| &                     END; \cr
  4472. WHILE e DO s &           |while(e) s;| &            WHILE e DO s; \cr
  4473. s; WHILE e &             |for(s;e;u) {| &           s; WHILE e DO BEGIN \cr
  4474. \quad t; u &             |  t;| &                   \quad t; u \cr
  4475. ENDWHILE &               |};| &                     END; \cr
  4476. \Esptab
  4477. REPEAT &                 |do {| &                   REPEAT \cr
  4478. UNTIL e &                |} while(!e);| &           UNTIL e; \cr
  4479. \Esptab
  4480. LOOP &                   |for(;;) {| &              WHILE TRUE DO BEGIN\rm (?) \cr
  4481. ENDLOOP &                |};| &                     END; \cr
  4482. \Esptab
  4483. SELECT x &               |switch(x) {| &            CASE x OF \cr
  4484. SELECT x OF y &          |switch(x) {| &            CASE x OF \cr
  4485. CASE 1; s... &           |case 1: s...; break| &    1: BEGIN s... END \cr
  4486. CASE a+1 &               -- &                       \rm -- \cr
  4487. CASE 1,2,3 &             |case 1: case 2: case3:| & 1,2,3: \cr
  4488. CASE "a".."z" &          -- &                       \rm -- \cr
  4489. ENDSELECT &              |};| &                     END \cr
  4490. \Esptab
  4491. INC x &                  |x++;| &                   x:=x+1; (INC()) \cr
  4492. DEC x &                  |x--;| &                   x:=x-1; (DEC()) \cr
  4493. JUMP lab &               |goto lab;| &              GOTO lab; \cr
  4494. x:=e &                   |x=e;| &                   x:=e; \cr
  4495. /* */ &                  |/* */| &                  |{ }| \cr
  4496. -> &                     |//| &                     \rm -- \cr
  4497. \bartab
  4498. \multispan3$^{(1)}$ mira |WHILE|; C no tiene |FOR|, |for| es otra forma de escribir |while|\hfil\cr
  4499. \multispan3$^{(2)}$ s\'olo |STEP -1| con |DOWNTO|\hfil\cr
  4500. \bigskip
  4501. \halign to\hsize{\tt#\hfil\tabskip=2em plus30em minus1em& #\hfil& \tt#\hfil\tabskip=0pt\cr
  4502. \bartab
  4503. \multispan3\sc VALORES\hfil\cr
  4504. \sc E&                    \sc C/C++&              \sc Pascal\cr
  4505. \bartab
  4506. 1 &                     |1| &                      1 \cr
  4507. 1.0 &                   |1.0| &                    1.0 \cr
  4508. \$1 &                   |0x1| &                    \rm ? \cr
  4509. \%1 &                   ? &                        \rm ? \cr
  4510. "a" &                   |'a'| &                    chr(97) (?) \cr
  4511. 'blabla' &              |"blabla"|&                'blabla' \cr
  4512. [1,2,3] &               --$^{(1)}$ &               \rm -- \cr
  4513. [1,2,3]:INT &           -- &                       \rm -- \cr
  4514. \bartab
  4515. \multispan3$^{(1)}$ |mifunc([1,2,3]) --> int temp[]={1,2,3}; mifunc(temp);|\hfil\cr
  4516. \medskip
  4517. \halign to\hsize{\tt#\hfil\tabskip=2em plus30em minus1em& #\hfil& \tt#\hfil\tabskip=0pt\cr
  4518. \bartab
  4519. \multispan3\sc OPERADORES\hfil\cr
  4520. \sc E&                   \sc C/C++&              \sc Pascal\cr
  4521. \bartab
  4522. + - * / &                |+ - * /| &              + - * DIV \cr
  4523. = <> > < >= <= &         |== != > < >= <=| &      = <> > < >= <= \cr
  4524. AND OR  (log) &          |&& |\|\| &              and or \cr
  4525. AND OR  (bit) &          |& |\| &                 \rm ? \cr
  4526. SIZEOF x &               |sizeof(x)| &            \rm -- \cr
  4527. `e &                     --&                      --$^{ (1)}$ \cr
  4528. \^{}x $^{ (4)}$ &        |*x| &                   ... \cr
  4529. $\{$x$\}$ &              |&x| &                   ... \cr
  4530. x++ &                    |x++| &                  \rm -- \cr
  4531. x-- &                    |--x| &                  \rm -- \cr
  4532. -x &                     |-x| &                   -x \cr
  4533. IF e THEN f ELSE g &     |e ? f : g| &            \rm -- \cr
  4534. x.y &                    |x->y| &                 x\^{}.y \cr
  4535. \rm -- &                 |x.y| &                  x.y \cr
  4536. x.y.z &                  |x->y->z| &              x\^{}.y\^{}.z \cr
  4537. x:=e &                   |x=e| &                  \rm -- \cr
  4538. e BUT f &                |(e,f)| &                \rm -- \cr
  4539. x[] &                    |x[0] *x|$^{(2)}$ &      x[0] \cr
  4540. x[1] &                   |x[1]| &                 x[1] \cr
  4541. x[1] $^{(3)}$ &          |&x[1]| &               \rm ? \cr
  4542. x[1].y &                 |x[1]->y| &              x[1]\^{}.y \cr
  4543. x[]++ &                  |*x++| &                 \rm -- \cr
  4544. x[1].y++ &               |*(x+1)++| &             \rm -- \cr
  4545. x::y.a &                 |((y *)x)->a| &          \rm -- \cr
  4546. x.y::z.a &               |((z *)x->y)->a| &       \rm -- \cr
  4547. \bartab
  4548. \multispan3$^{(1)}$ mira expresiones entrecomilladas.\hfil\cr
  4549. \multispan3$^{(2)}$ otros tambi\'en mantienen la equivalencia entre |*(x+e)| y |x[e]|.\hfil\cr
  4550. \multispan3$^{(3)}$ con |ARRAY OF |\<objeto>\hfil\cr
  4551. \multispan3$^{(4)}$ {\bf s\'olo} para pasar por referencia. En otro caso: |[]|\hfil\cr
  4552. \medskip
  4553. \halign to\hsize{\tt#\hfil\tabskip=2em plus30em minus1em& #\hfil\tabskip=0pt\cr
  4554. \bartab
  4555. \multispan2\sc PROGRAMACION ORIENTADA A OBJETOS\hfil\cr
  4556. \sc E&                    \sc C/C++\cr
  4557. \bartab
  4558. OBJECT x &                 |class x {| \cr
  4559. OBJECT x OF y &            |class x : y {| \cr
  4560. self.i &                   |this->i| \cr
  4561. PROC a OF x IS self.i &    |virtual int x::a() { return i; }| \cr
  4562. \rm -- &                   |int x::a() { return i; }| \cr
  4563. PROC a OF x IS EMPTY &     |virtual int x::a() =0| \cr
  4564. PUBLIC &                   |public:| \cr
  4565. a.method$^{(1)}$ &         |a->method|$^{(1)}$ \cr
  4566. \bartab
  4567. \multispan2$^{(1)}$ mira tambi\'en en el siguiente apartado en NEW\hfil\cr
  4568. \medskip
  4569. \halign to\hsize{\tt#\hfil\tabskip=2em plus30em minus1em& #\hfil& \tt#\hfil\tabskip=0pt\cr
  4570. \bartab
  4571. \multispan3\sc CONSTANTES/TIPOS\hfil\cr
  4572. \sc E&                    \sc C/C++&              \sc Pascal\cr
  4573. \bartab
  4574. CONST X=1 &             |#define X 1| &           CONST X=1; \cr
  4575. &                       |const int X=1;| \cr
  4576. ENUM X,Y,Z &            |#define X 0 (etc.)| &    TYPE x=(X,Y,Z); \cr
  4577. &                       |enum x{X,Y,Z};| \cr
  4578. SET X,Y,Z &             -- &                      TYPE x=SET OF (X,Y,Z); \cr
  4579. DEF &                   &                         VAR \cr
  4580. x &                     |int x; (or: long x;)| &  x:INTEGER; \cr
  4581. x:LONG &                |int x;| &                x:INTEGER; \cr
  4582. x:PTR TO y &            |struct y* x;| &          x:\^{}y; \cr
  4583. x:y &                   |struct y x;| &           x:y; \cr
  4584. x[10]:ARRAY OF y &      |struct y x[10];| &       x:ARRAY [0..9] OF y; \cr
  4585. x[10]:STRING &          --$^{(1)}$ &              x:STRING[10];$^{(2)}$ \cr
  4586. x[10]:LIST &            --$^{(1)}$ &              \rm --$^{(1)}$ \cr
  4587. x:REG &                 |register int x;| \cr
  4588. OBJECT x &              |struct x {|$^{(3)}$ &    TYPE x = RECORD \cr
  4589. \qquad y:CHAR,z:INT &   |  char y; short z;| &    \qquad y:CHAR; z:INTEGER; \cr
  4590. ENDOBJECT &             |};| &                    END; \cr
  4591. \bartab
  4592. \multispan3$^{(1)}$ en C sim\'ulalo con un arreglo de char/int con comprobaci\'on de rango propia.\hfil\cr
  4593. \multispan3$^{(2)}$ no en Wirth Pascal, pero disponible en todos los dialectos populares.\hfil\cr
  4594. \multispan3$^{(3)}$ o clase p\'ublica.\hfil\cr
  4595. \medskip
  4596. \halign to\hsize{\tt#\hfil\tabskip=2em plus30em minus1em& #\hfil& \tt#\hfil\tabskip=0pt\cr
  4597. \bartab
  4598. \multispan3\sc FUNCIONES PREDIFINIDAS Y RESERVA DE MEMORIA\hfil\cr
  4599. \multispan3\sl (s\'olo algunas funciones como ejemplo.)\hfil\cr
  4600. \sc E&                    \sc C/C++&              \sc Pascal\cr
  4601. \bartab
  4602. WriteF(fs,...) &         |printf(fs,...);| &      WriteLn(a,b,...); \cr
  4603. &                        |cout << a << b ... ;| \cr
  4604. ReadStr(f,s) &           |scanf(fs,...)| &        ReadLn(s) \cr
  4605. Val(s) &                 &                        Val() \cr
  4606. &                        |cin >> s;| \cr
  4607. StrCopy(s,s,n)$^{(1)}$ & |strcpy(s,s)| &          s:=s;$^{(2)}$ \cr
  4608. \Esptab
  4609. Mod(e,e) &               |e%e| &                  e MOD e \cr
  4610. Shl(e,n) &               |e<<n| &                 Shl() \cr
  4611. Long(e) &                -- &                     \rm -- \cr
  4612. \Esptab
  4613. p:=New(e) &              |p=malloc(e);| &         New(p); \cr
  4614. NEW p &                  |p=new type;| \cr
  4615. NEW p.constr() &         |p=new constr()| &       \rm -- \cr
  4616. NEW [e,f,g] &            -- &                     \rm -- \cr
  4617. Dispose(p) &             |free(p);| &             Dispose(p); \cr
  4618. END p &                  |delete p;| \cr
  4619. \bartab
  4620. \multispan3$^{(1)}$ aseg\'urate de convertir los arreglos de char en |STRING|s de verdad. \hfil\cr
  4621. \multispan3$^{(2)}$ no se que funci\'on se necesita en el caso de punteros.\hfil\cr
  4622. \medskip
  4623. \halign to\hsize{\tt#\hfil\tabskip=2em plus30em minus1em& #\hfil& \tt#\hfil\tabskip=0pt\cr
  4624. \bartab
  4625. \multispan3\sc UNIFICCION Y CELDAS LISP\hfil\cr
  4626. \sc E&                   \sc LISP&              \sc PROLOG\cr
  4627. \bartab
  4628. <1\|2> &                 |(1 . 2)| &            [1\|2] \cr
  4629. <1,2,3> &                |(1 2 3)| &            [1,2,3] \cr
  4630. <1,2\|3> &               |(1 2 . 3)| &          [1,2\|3] \cr
  4631. \esptab
  4632. \sc E&                   \sc HASKELL&           \sc PROLOG\cr
  4633. \bartab
  4634. e <=> <x\|y> &           |(x:y) = e| &          e = [X\|Y] \cr
  4635. e <=> <1,2,x> &          |[1,2,x] = e| &        e = [1,2,X] \cr
  4636. e <=> [1,x] &            -- &                   \rm -- \cr
  4637. \bartab
  4638. \bigskip
  4639. \halign to\hsize{\tt#\hfil\tabskip=2em plus30em minus1em& #\hfil& \tt#\hfil\tabskip=0pt\cr
  4640. \bartab
  4641. \multispan3\sc EXPRESIONES ENTRECOMILLADAS\hfil\cr
  4642. \esptab
  4643. \sc E&                    \sc LISP&              \sc MIRANDA\cr
  4644. \bartab
  4645. `e &                    |(QUOTE e)  'e| &        $^{(3)}$ \cr
  4646. &                       |(LAMBDA () e)| &        $^{(1)}$ \cr
  4647. `x+y &                  |'(+ x y)| \cr
  4648. Eval(`e) &              |(EVAL `e)| \cr
  4649. ForAll(v,l,`e) &        --$^{(2)}$ \cr
  4650. MapList(v,l,l,`e) &     |(MAPCAR (LAMBDA (V) E) L)| & map ($\backslash$v->e) l \cr
  4651. \bartab
  4652. \multispan3$^{(1)}$ realmente |QUOTE|, pero usado a veces donde en |LISP| se usar\'{\i}a |LAMBDA|,
  4653.     como en |MapList|()\hfil\cr
  4654. \multispan3$^{(2)}$ ni siquiera en ProLog, mira en otros lenguajes de l\'ogica.\hfil\cr
  4655. \multispan3$^{(3)}$ en su lugar se usar\'{\i}a 'lazyness'\hfil\cr
  4656. \espacio
  4657. Ejemplo:
  4658. \Ejemplos
  4659. \qquad E: &       |MapList({x},[1,2,3,4],a,`x*x)| \cr
  4660. \qquad MIRANDA: & |map (\x->x*x) [1,2,3,4]| \cr
  4661. \qquad LISP: &    |(MAPCAR (LAMBDA (X) (* X X) `(1 2 3 4))| \cr
  4662. \bigskip
  4663. \halign to\hsize{\tt#\hfil\tabskip=2em plus30em minus1em& #\hfil& \tt#\hfil\tabskip=0pt\cr
  4664. \bartab
  4665. \multispan3\sc EXCEPCIONES\hfil\cr
  4666. \esptab
  4667. \sc E&                    \sc C/C++&                 \sc ADA\cr
  4668. \bartab
  4669. PROC x() HANDLE &         |int x() { try {| &        function x is begin \cr
  4670. EXCEPT &                  |} catch (exc) {|$^{(1)}$& exception \cr
  4671. EXCEPT DO &               -- &                       \rm -- \cr
  4672. ENDPROC &                 |}};| &                    end x; \cr
  4673. \Esptab
  4674. Raise(e) &                |throw e;| &               raise e; \cr
  4675. Throw(e,f) &              ? &                        \rm -- \cr
  4676. ReThrow() &               |throw e;| &               raise e; \cr
  4677. RAISE "MEM" IF New()=0 &  -- &                       \rm --$^{(2)}$ \cr
  4678. \bartab
  4679. \multispan3$^{(1)}$ |catch| s\'olo controla un excepci\'on concreta, es bastante diferente de como se usan los\hfil\cr
  4680. \multispan3 \quad manejadores de excepciones generales en E. \hfil\cr
  4681. \multispan3$^{(2)}$ el sistema en tiempo de ejecuci\'on lanza algunas excepciones, pero no estoy seguro de\hfil\cr
  4682. \multispan3 \quad si se pueden {\it definir} excepciones lanzadas autom\'aticamente en ADA. \hfil\cr
  4683. \bigskip
  4684. \noin En las tablas aparec\'{\i}an una serie de abreviaturas y signos cuyo significado es
  4685. el siguiente:
  4686. \Ejemplos
  4687. \qquad --&      = caracter\'{\i}stica no disponible en el lenguaje en cuesti\'on.\cr
  4688. \qquad ?&       = el autor no tiene idea a qu\'e se traduce esa caracter\'{\i}stica. (o no est\'a seguro).\cr
  4689. \qquad ...&     = puede estar disponible, pero no en relaci\'on 1:1 que la haga interesante.\cr
  4690. \qquad x,y,z&   = indetificadores arbritarios.\cr
  4691. \qquad e,f,g&   = expresiones arbritarias.\cr
  4692. \qquad s,t,u&   = sentencias arbritarias.\cr
  4693. \qquad i,j,k&   = enteros arbritarios.\cr
  4694. \qquad etc.\cr
  4695. \endchapter\saltacap
  4696. \beginchapter Ap\'endice B. FAQ
  4697. \ninepoint
  4698.    Esta  lista-FAQ (Frequently Asked Questions\nota{Preguntas realizadas
  4699. con Frecuencia, de fecha 1-10-04 al 1-12-94}) ha sido recogida mirando en el
  4700. email viejo y escongiendo aquellas preguntas que se repet\'{\i}an una y otra vez.
  4701. \medskip
  4702. \parindent=0pt
  4703. \advance\leftskip by15pt
  4704. \advance\rightskip by15pt
  4705. {\bf Compilador/Enlazador/Ejecutables}
  4706. \pregunta{?`C\'omo puedo enlazar c\'odigo~E con otros lenguajes\b/usar un formato de
  4707.           objeto estandard?}
  4708.   La conversi\'on entre |.m| y |.o| no  es en realidad un  gran problema,  como
  4709.   podemos ver con la utilidad |o2m|,  que permite la cooperaci\'on entre~E  y
  4710.   macro-ensambladores bastante  bien.  El  problema con el~C radica  en el
  4711.   c\'odigo compilado,  no  el  formato del  fichero.  A no ser  C~trivial,
  4712.   cualquier c\'odigo compilado en~C  har\'a referencia a cosas como |_DOSBase|,
  4713.   librer\'{\i}as  de enlace,  bases  de  pila,  y otras  cosas  del c\'odigo  de
  4714.   inicializaci\'on  que~E  proporciona  de una  forma  algo diferente,  por
  4715.   ejemplo, el c\'odigo  de inicializaci\'on de E es bastante  diferente de el
  4716.   de los compiladores de~C\null{}. Estos problemas pueden aparecer incluso entre
  4717.   dos  compiladores de~C\null{}.  Si  puedes conseguir  que tu  compilador de~C
  4718.   genere un |.o|  sin referencias externas, etc, entonces podr\'as enlazarlo
  4719.   con~E (yo ya lo he hecho una vez con MaxonC++).
  4720. \pregunta{?`Puedo enlazar con \/|amiga.lib|?}
  4721.   De momento no.  Aunque en menor medida, esto tiene los mismos problemas
  4722.   que los  ficheros |.o|,  aunque con la ayuda de  un ensamblador y  |o2m| se
  4723.   podr\'{\i}a traducir un fichero |.lib| a |.m|, de hecho, ya se ha realizado para
  4724.   algunas.  S\'olo es cuesti\'on de tiempo  que alguien lo haga  para (partes
  4725.   de) |amiga.lib|.
  4726. \pregunta{?`Se puede hacer residente el c\'odigo de~E?}
  4727.   Practicamente {\bf todo}  el c\'odigo de E  ya se puede hacer  residente sin la
  4728.   ayuda del programador.  Seg\'un creo, la \'unica construcci\'on~E  que puede
  4729.   violar \'esto es un lista est\'atica |[]| con una expresi\'on en ella (como |[a]|
  4730.   por ejemplo. Con |[1]| y |NEW [a]| van bien).
  4731. \pregunta{Tengo una aplicaci\'on con ensamblador en l\'{\i}nea, y con |OPTI/S|
  4732.           no funciona bien.  ?`Qu\'e sucede?}
  4733.   El ensamblador en l\'{\i}nea puede usar los mismos registros a la vez que el
  4734.   opimizador de registros.  Busca en otra parte del documento sobre eso.
  4735. \pregunta{He escrito \/|X| tanto en~C como en~E, y la versi\'on en~E es
  4736.           \/|Y|~veces m\'as r\'apida\b/lenta. ?`A~qu\'e se debe?}
  4737.   No  es f\'acil  hacer una  comparaci\'on  de forma  totalmente objetiva.  A
  4738.   menudo, se  puede dar el  caso que alguno de los dos tenga  rutinas m\'as
  4739.   optimizadas para  algo (manejo de cadenas, E/S,  etc~\dots).  El uso  de un
  4740.   profiler  puede ayudar  a descubrirlo.  Si  el c\'odigo en cuesti\'on  s\'olo
  4741.   realiza c\'alculos, no hay ninguna raz\'on por la que alguno de los dos sea
  4742.   significativamente m\'as lento que el otro, si se usan correctamente.
  4743. \pregunta{He escrito un buen \/|misutils.m|, y aunque s\'olo use una funci\'on
  4744.           suya, \/|EC|~lo enlaza todo.  !`No me gusta!.}
  4745.   El estilo  de escritura de  m\'odulos en  E es mantenerlos  como unidades
  4746.   relativamente peque\~nas,  s\'olo con c\'odigo y datos  relacionados.  (Esto
  4747.   tiene m\'as sentido  si sabes que el m\'odulo es  la unidad de ocultamiento
  4748.   de datos de~E\null{}).  !`Div\'{\i}delo!
  4749. \pregunta{?`Puedo dejar |EC| residente?}
  4750.   No, de momento no.  El propio |EC| esta escrito en un estilo de
  4751.   ensamblador anticuado, y no se puede hacer residente |;-)|
  4752. \Espacio
  4753. {\bf Recursos}
  4754. \pregunta{En la documentaci\'on no se explican las funciones de
  4755.           |intuition.library|,~\dots\quad ?`Por qu\'e?}
  4756.   Esas funciones no son parte de E, sino que forman parte del SO de Amiga.
  4757.   Como tales,  se describen  en los  documentos de  Commodore,  no en los
  4758.   documentos de E\null{}. ``{\sl The AMIGA ROM Kernel Reference Manuals\/}'' son una serie
  4759.   de libros publicados  por  Addison Wesley.  Un  buen  lugar por  donde
  4760.   empezar es  el libro de  ``{\sl Libraries\/}'' de esa serie,  ISBN~0-201-56774-1.
  4761.   Tambi\'en hay otros libros que merecen la pena ser considerados,  como el
  4762.   ``{\sl The Amiga Guru Book\/}'' de Ralph Babel.
  4763. \pregunta{Me gustar\'{\i}a leer m\'as c\'odigo fuente a parte del que viene con la
  4764.           distribuci\'on,  ?`Donde debo buscar?}
  4765.   Hay cantidad  de lugares  en los  que mirar,  aunque  el mejor sin duda
  4766.   alguna  es {\it Aminet}  (Una colecci\'on de  sites de  FTP  en Internet),  por
  4767.   ejemplo |ftp.luth.se|.  En el directorio  |/pub/aminet/dev/e| encontrar\'as
  4768.   todo tipo de cosas relacionadas con~E\null{}.  Algunas BBSs  fuera de Internet
  4769.   tambi\'en  tienen {\it Aminet},  e incluso hay disponibles  CDROMS\null{}.  Otro  buen
  4770.   lugar para recoger  fuentes y hablar con buenos programadores en~E,  es
  4771.   la lista  de correo  de~E\null{}.  Env\'{\i}a un email  con ``|HELP|''  en el  cuerpo a
  4772.   |amigae-request@bkhouse.cts.com| para escuchar todo sobre  ello.  Tambi\'en
  4773.   hay discusiones sobre~E en otras redes ({\it FidoNet},  {\it AmigaNet\/}), series de
  4774.   discos de dominio  p\'ublico (EPD en Europa\b/Alemania,  la misma direcci\'on
  4775.   que el lugar de registro alem\'an), adem\'as, hay gran cantidad de clubs de
  4776.   usuarios, BBS que apoyan~E\null{}.  Simplemente echa un vistazo en tu zona.
  4777. \pregunta{He oido hablar de esa lista de correo. ?`Qu\'e tal est\'a?}
  4778.   Compruebalo  tu  mismo.  Si  vas en serio  con~E,  es  definitivamente
  4779.   imprescindible, adem\'as de que es el primer lugar en el que aparecen las
  4780.   noticias sobre~E.
  4781. \pregunta{He tenido problemas para introducirme en la lista.  ?`Podr\'{\i}as
  4782.           ocuparte tu de eso por mi?}
  4783.   Yo  no  tengo,  personalmente, nada que ver con la administraci\'on de la
  4784.   lista,  de  forma  que  no  te  puedo  ayudar  m\'as  que cualquier otro.
  4785.   Recuerda que el servidor es un proceso autom\'atizado, de forma que debes
  4786.   ser preciso en lo que le envias.  No env\'{\i}es correo administrativo  a la
  4787.   lista, en su lugar, intenta contactar con el administrador.
  4788. \pregunta{Soy nuevo en Internet.  ?`Me ayudar\'{\i}as a conseguir la lista de
  4789.           correo, ficheros FTP de {\it Aminet}, etc~\dots?}
  4790.   Cosas de  este tipo  van m\'as  all\'a de mi  cometido.  Por favor, intenta
  4791.   contactar localmente con alguien.
  4792. \pregunta{?`C\'omo se cual es la \'ultima versi\'on y c\'omo la recibo?}
  4793.   Si  estas  en  la  lista  de   correo  ser\'as  el  primero  en  saberlo.
  4794.   {\it Aminet}  es el  primer lugar  en el  que aparecen  las distribuciones  y
  4795.   actualizaciones. Los usuarios registrados obtendr\'an las actualizaciones
  4796.   y/o notas de forma autom\'atica en su mbox.
  4797. \pregunta{?`C\'omo registrarse?}
  4798.   Por favor mira en otra parte de este documento.
  4799. \pregunta{?`Existe E para otras plataformas?}
  4800.   No  todav\'{\i}a.  Me  he comprometido personalmente  con  un proyecto  para
  4801.   realizar compiladores\b/traductores,  y algunos otros tienen proyectos de
  4802.   compilador~E para otras plataformas, aunque de momento a\'un no hay nada.
  4803. \pregunta{?`Puedo convertirme en un lugar de registro para el pa\'{\i}s~\/|X|?}
  4804.   Generalmente  los  lugares los  elijo  yo  mismo  cuando creo  que  es
  4805.   necesario y conozco muy bien a alguien en ese pa\'{\i}s.
  4806. \pregunta{?`Puedo apoyar E con una BBS / con un club de programaci\'on~\dots?}
  4807.   Siempre puedes hacerlo, sin falta de preguntarme.  Aunque por supuesto,
  4808.   me gusta tener noticias sobre esfuerzos de ese tipo~\dots
  4809. \Espacio
  4810. {\bf Programaci\'on}
  4811. \pregunta{?`Puedo hacer \/|X| en E?  (donde \/|X| = $\{$\/juegos, autoedici\'on,~\dots$\}$)}
  4812.   E es  un lenguaje de programaci\'on  de prop\'osito general,  por lo que no
  4813.   deber\'{\i}a haber ning\'un tipo de programa que  no se pueda hacer con~E (con
  4814.   alguna rara excepci\'on,  que  est\'a cubierta con  el ensamblador en l\'{\i}nea
  4815.   de~E\null{}). Esto no significa que~E est\'e equipado especialmente para ciertos
  4816.   tipos  de programas,  es decir,  E~no  tiene funciones  especiales para
  4817.   juegos (aunque su extensibilidad permite incorporarlas facilmente).
  4818. \pregunta{?`C\'omo creo \/|X| en E?  (donde \/|X| = $\{$\/ventana, manejador de
  4819.           interrupciones,~\dots$\}$)}
  4820.   Al igual  que en la  pregunta anterior,  E~s\'olo abre la posibilidad de
  4821.   escribir lo que quieras, y no siempre tiene una funci\'on espec\'{\i}fica.  En
  4822.   el peor  de los casos  eso significar\'a  el usar funciones  dif\'{\i}ciles de
  4823.   alguna librer\'{\i}a,  aunque merece la pena meterte en detalle con eso.  Si
  4824.   tienes suerte alg\'un  otro programador ya habr\'a  realizado algo parecido
  4825.   de lo que puedas aprender.
  4826. \pregunta{Por favor escr\'{\i}beme un ejemplo de como hacer \/|X| en~E.}
  4827.   Por favor, intente imaginartelo t\'u mismo,  o pregunta a otros programadores de~E.
  4828. \pregunta{El compilador no quiere compilar cosas como \/|mipantalla.rastport.bitmap|,
  4829.           incluso cuando en general \/|x.y.z| es posible. ?`Por qu\'e?}
  4830.   Para poder  hacer referencia al  \'ultimo |bitmap|,  el compilador necesita
  4831.   saber el  tipo de la  expresi\'on |mipantalla.rastport|.  Y si miras  en el
  4832.   m\'odulo |intuition/screens.m| ver\'as que el campo |rastport| no tiene tipo.
  4833. \pregunta{\dots ?`por qu\'e no tenemos nuevos m\'odulos con tipos corregidos?}
  4834.   Porque los includes en ensamblador (|.o|) de los cuales se convierten los
  4835.   m\'odulos~E no contienen esa informaci\'on.  No se pueden usar los ficheros
  4836.   |.h| de~C en su lugar, porque usan de alguna forma otros identificadores,
  4837.   y romper\'{\i}a la compatibiladad anterior.
  4838. \pregunta{\dots entonces, ?`qu\'e hago?}
  4839.   El m\'etodo cl\'asico es poner |x.y|  en un puntero con tipo, y entoces hacer
  4840.   referencia a |.z|  desde \'ese.  Con la mutaci\'on de punteros en~v3, tambi\'en
  4841.   puedes hacer referencia a \'el directamente (m\'{\i}ralo en otra parte de este
  4842.   documento).
  4843. \pregunta{Cuando escribo c\'odigo como el siguiente el compilador me lo acepta,
  4844.           pero m\'as tarde me da problemas.  ?`Qu\'e hay mal en este c\'odigo?}
  4845.   \qquad|DEF s[100]:STRING|\par
  4846.   \qquad|s:='mi bonita cadena'|
  4847. \smallskip
  4848.   Si estas acostumbrado al  {\sc BASIC},  por  ejemplo,  estar\'as acostumbrado a
  4849.   usar las cadenas  de la misma forma  que los enteros,  ya que ambos son
  4850.   {\sl valores}.  Sin embargo  en~E no  hay variables  cadena  reales en  el
  4851.   sentido  del {\sc BASIC},  el  |DEF| anterior  crea un  trozo  de memoria  para
  4852.   almacenar  la cadena,  luego fija  la variable  como un  puntero a  esa
  4853.   memoria.  El puntero y la memoria son, aparte de la implementaci\'on, dos
  4854.   entidades no relacionadas.  A partir del |DEF|, todas las operaciones que
  4855.   acceden directamente a  |s| est\'an accediendo al puntero.  La asignaci\'on
  4856.   pone la  direccion de  |mi bonita cadena|  en |s|,  sobreescribiendo el
  4857.   valor anterior.  La memoria  de cadena  creada por  el |DEF|  se mantiene
  4858.   inalterada, y ahora inaccesible ya que no hay ning\'un puntero que apunte
  4859.   ella.  Las  funciones  como  |StrCopy()| pueden  usar  ese  puntero  para
  4860.   encontrar la memoria real, y rellenarla:
  4861.   \qquad|StrCopy(s,'mi bonita cadena')|
  4862.   es  correcto.  Por  supuesto,  la asiganci\'on  de  cadenas como punteros
  4863.   tambi\'en es de utilidad, por ejemplo,  si s\'olo quieres leer los datos de
  4864.   la cadenas, y no hacer nada m\'as con ellos, entonces:
  4865.   \qquad|DEF s:PTR TO CHAR|
  4866.   no  reserva  ninguna  memoria  para  la cadena,  s\'olo  el  puntero.  La
  4867.   asignaci\'on anterior  tendr\'{\i}a sentido ahora.  Todo esto  nos lleva  a la
  4868.   diferencia entre punteros y valores (o sem\'antica por valor\b/referencia),
  4869.   y es importante que lo entiendas para programar en~E con \'exito.
  4870. \pregunta{?`Como retorno un \/|STRING|, |OBJECT|, etc. de una funci\'on?}
  4871.   Depende.  Si  s\'olamente  quieres   utilizarlo  como  valor  de  retorno
  4872.   temporal,  pasa  una cadena  como  argumento  y  deja que la rutina  la
  4873.   rellene.  Si   necesitas  crear  una  cadena\b/objeto   nuevo,  reserv\'alo
  4874.   din\'amicamente dentro de la funci\'on, y retorna el puntero.
  4875. \Espacio
  4876. {\bf Errores}
  4877. \pregunta{Recuerdo cuando estaba programando algo que de pronto el compilador
  4878.           rompi\'o\b/funcion\'o mal\b/produjo un error interno\b/gener\'o mensajes
  4879.           de error err\'oneos.  ?`No deber\'{\i}as hacer algo sobre esto?}
  4880.   Si no tengo pistas sobre donde buscar un error, no podr\'e corregirlo. Si
  4881.   te  encuentras  con algo  que  estas  seguro de  que  es  un error  del
  4882.   compilador, haz una copia del fuente que reproduce el error (si puedes
  4883.   recorta el fuente al m\'{\i}mino manteniendo el error) y env\'{\i}amelo con tanta
  4884.   informaci\'on como sea posible.  Por ejemplo, los hits de  |Enforcer| de~|EC|
  4885.   son bastante \'utiles.
  4886. \pregunta{He escrito un programa \/|X|, pero rompe.  Estoy seguro de que no tiene
  4887.           errores, por lo que debe ser un error del compilador.}
  4888.   Debido a la falta de tipos de E, nunca puedes estar completamente
  4889.   seguro de que tu c\'odigo es correcto.  La mayor parte del c\'odigo que se
  4890.   me envi\'o con comentarios como el anterior se comprob\'o m\'as tarde que
  4891.   eran errores en el c\'odigo, casi siempre debidos a una falta de
  4892.   conocimiento de~E\null{}.\quad !`Lee la documentaci\'on, y usa |EDGB|!
  4893. \Espacio
  4894. {\bf Caracteristicas Futuras}
  4895. ?`Tendr\'a E~\dots
  4896. \pregunta{argumentos en registros?}
  4897.   Estoy seguro de que es posible, pero como muchas otras cosas, no es
  4898.   prioritario para m\'{\i}.
  4899. \pregunta{enlazador de librer\'{\i}a/dispositvo (Library\b/Device)?}
  4900.   Ya lo habr\'{\i}a hecho si no fuera por la forma en que~E guarda la
  4901.   variables globales (en la pila), lo cual complica las cosas bastante.
  4902.   Esto simplemente necesitar\'a algo de tiempo.
  4903. \pregunta{herencia m\'ultiple?}
  4904.   No es posible en E\null{}.  La herencia m\'ultiple rompe la compatibilidad
  4905.   estructural entre objetos, y necesita de una comprobaci\'on de tipos
  4906.   bastante severa para resolverlo.
  4907. \pregunta{|PROC|s dentro de |PROC|s?}
  4908.   No creo.
  4909. \pregunta{arreglos multidimensionales?}
  4910.   Tampoco lo creo.  Realmente en E no hay nada parecido a un arrreglo,
  4911.   s\'olo punteros que apuntan a grandes cantidades de objetos del mismo
  4912.   tama\~no.  Para tener arreglos de dos dimensiones, ser\'{\i}a necesario tener
  4913.   el concepto de {\sl tama\~no\/} de un arreglo, lo cual~E no tiene.
  4914. \pregunta{m\'as aopoyo a |020|/|881|?}
  4915.   Si, eventualmente.  Aunque no est\'a entre las primeras cosas a realizar.
  4916. \pregunta{sintaxis compatible con C?}
  4917.   A menudo la gente est\'a acostumbrada a alg\'un tipo de lenguaje
  4918.   (principalmente~C), y no entiende porque el dise\~no de un lenguaje de
  4919.   programaci\'on no es tan configurable como una utilidad de directorio o
  4920.   un editor de texto:\par
  4921.   {\obeylines
  4922.   \qquad {\sl Prefiero |==|/|=| m\'as que |=|/|:=|}
  4923.   \qquad {\sl ?`No puedes intercambiar |"| y |'| ?}
  4924.   \qquad {\sl ?`Por qu\'e |--| no funciona como en C?}
  4925.   \qquad {\sl !`Odio escribir las palabras clave en may\'usculas!}
  4926.   \qquad {\sl !`La falta de precedencia es odiosa!}}
  4927.   Las caracter\'{\i}sticas {\sl referidas} arriba jam\'as cambiar\'an, y ser\'a
  4928.   mejor que te acostumbres a ellas.  Todas las decisiones de dise\~no tienen
  4929.   buenas razones, y al contrario de lo que dicen algunos rumores, no se
  4930.   hicieron por razones de velocidad del compilador (de hecho, el implementarlas
  4931.   de una forma tradicional no har\'{\i}a m\'as lento al compilador).
  4932. \pregunta{?`Por qu\'e la caracteristica~\/|X| en~E no es como en el lenguaje~\/|Y|?
  4933.           (que yo encuentro mejor).}
  4934.   Lo mismo que antes, el dise\~no de un lenguaje no se puede cambiar debido
  4935.   a una preferencia personal.  Si tienes ideas serias de c\'omo debe ser un
  4936.   lenguaje seg\'un tus preferencias, y esas ideas provienen del lenguaje |Y|,
  4937.   entonces utiliza |Y|\null{}.  Si no encuentras tus ideas en ning\'un lenguaje
  4938.   existente, entonces !`es el momento de dise\~nar e implementar el tuyo
  4939.   propio!  (No me estoy burlando, !`merece la pena!, y siempre puedes
  4940.   empezar con~E~\dots |:-)|)
  4941. \pregunta{quiz\'as \/|X|?}
  4942.   Despu\'es de haber visto pr\'acticamente cientos de lenguajes de
  4943.   programaci\'on, las posibilidades que tienes de sugerir una nueva
  4944.   caracter\'{\i}stica para~E en la que no haya pensado, no son muy grandes.
  4945.   Muchas cosas no son apropiadas para~E, y en general el tiempo est\'a
  4946.   limitado para a\~nadir cosas m\'as interesante.  (Si te fijas bien, la
  4947.   cantidad de caracter\'{\i}sticas de~E ya es bastante alta para un lenguaje
  4948.   de programaci\'on medio).  Tengo una lista bastante grande de posibles
  4949.   caracter\'{\i}sticas para~E, y se implementar\'an eventualmente algunas de
  4950.   ellas.  S\'olo espera y ver\'as~\dots
  4951. \endchapter
  4952. \eject
  4953. ------------Corta por aqu
  4954.  -------------------
  4955. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4956. %    Definitionen zur Unterst
  4957. tzung des ECMA 94 Latin 1 Zeichensatzes.
  4958. %    Zusammengeleimt von Olaf `Olsen' Barthel, 7. April 1991
  4959. %        use or misuse this file as you like...
  4960. %    Probleme gibt es noch bei den Zeichen f
  4961. r Yen, Cent und das
  4962. %    isl
  4963. ndische Thorr. Hier m
  4964. te man eigentlich mit Metafont
  4965. %    zuschlagen, wozu ich als TeX-Apprentice leider noch nicht
  4966. %    in der Lage bin :-(
  4967. %    little changes (hes) 9-jul-91
  4968. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4969. % See the new `lplain.tex' for TeX 3.0 (>= Version 2.09  Feb 8, 1990)
  4970. % if not(TeX >= 3.0) do_nothing else ...
  4971. \ifx\undefined\inputlineno \else
  4972. \ifnum\inputlineno=-1 \else
  4973. \message{AMIGA-style (ECMA 94 Latin 1)}
  4974. \lccode`
  4975. \uccode`
  4976. \lccode`
  4977. \uccode`
  4978. \catcode`
  4979. =\active \def 
  4980. {\`{a}}
  4981. \catcode`
  4982. =\active \def 
  4983. {\`{A}}
  4984. \lccode`
  4985. \uccode`
  4986. \lccode`
  4987. \uccode`
  4988. \catcode`
  4989. =\active \def 
  4990. {\'{a}}
  4991. \catcode`
  4992. =\active \def 
  4993. {\'{A}}
  4994. \lccode`
  4995. \uccode`
  4996. \lccode`
  4997. \uccode`
  4998. \catcode`
  4999. =\active \def 
  5000. {\^{a}}
  5001. \catcode`
  5002. =\active \def 
  5003. {\^{A}}
  5004. \lccode`
  5005. \uccode`
  5006. \lccode`
  5007. \uccode`
  5008. \catcode`
  5009. =\active \def 
  5010. {\~{a}}
  5011. \catcode`
  5012. =\active \def 
  5013. {\~{A}}
  5014. \lccode`
  5015. \uccode`
  5016. \lccode`
  5017. \uccode`
  5018. \catcode`
  5019. =\active \def 
  5020. {\"{a}}
  5021. \catcode`
  5022. =\active \def 
  5023. {\"{A}}
  5024. \lccode`
  5025. \uccode`
  5026. \lccode`
  5027. \uccode`
  5028. \catcode`
  5029. =\active \def 
  5030. {\aa}
  5031. \catcode`
  5032. =\active \def 
  5033. {\AA}
  5034. \lccode`
  5035. \uccode`
  5036. \lccode`
  5037. \uccode`
  5038. \catcode`
  5039. =\active \def 
  5040. {\ae}
  5041. \catcode`
  5042. =\active \def 
  5043. {\AE}
  5044. \lccode`
  5045. \uccode`
  5046. \lccode`
  5047. \uccode`
  5048. \catcode`
  5049. =\active \def 
  5050. {\c{c}}
  5051. \catcode`
  5052. =\active \def 
  5053. {\c{C}}
  5054. \lccode`
  5055. \uccode`
  5056. \lccode`
  5057. \uccode`
  5058. \catcode`
  5059. =\active \def 
  5060. {\`{e}}
  5061. \catcode`
  5062. =\active \def 
  5063. {\`{E}}
  5064. \lccode`
  5065. \uccode`
  5066. \lccode`
  5067. \uccode`
  5068. \catcode`
  5069. =\active \def 
  5070. {\'{e}}
  5071. \catcode`
  5072. =\active \def 
  5073. {\'{E}}
  5074. \lccode`
  5075. \uccode`
  5076. \lccode`
  5077. \uccode`
  5078. \catcode`
  5079. =\active \def 
  5080. {\^{e}}
  5081. \catcode`
  5082. =\active \def 
  5083. {\^{E}}
  5084. \lccode`
  5085. \uccode`
  5086. \lccode`
  5087. \uccode`
  5088. \catcode`
  5089. =\active \def 
  5090. {\"{e}}
  5091. \catcode`
  5092. =\active \def 
  5093. {\"{E}}
  5094. \lccode`
  5095. \uccode`
  5096. \lccode`
  5097. \uccode`
  5098. \catcode`
  5099. =\active \def 
  5100. {\`{\i}}
  5101. \catcode`
  5102. =\active \def 
  5103. {\`{I}}
  5104. \lccode`
  5105. \uccode`
  5106. \lccode`
  5107. \uccode`
  5108. \catcode`
  5109. =\active \def 
  5110. {\'{\i}}
  5111. \catcode`
  5112. =\active \def 
  5113. {\'{I}}
  5114. \lccode`
  5115. \uccode`
  5116. \lccode`
  5117. \uccode`
  5118. \catcode`
  5119. =\active \def 
  5120. {\^{\i}}
  5121. \catcode`
  5122. =\active \def 
  5123. {\^{I}}
  5124. \lccode`
  5125. \uccode`
  5126. \lccode`
  5127. \uccode`
  5128. \catcode`
  5129. =\active \def 
  5130. {\"{\i}}
  5131. \catcode`
  5132. =\active \def 
  5133. {\"{I}}
  5134. \lccode`
  5135. \uccode`
  5136. \lccode`
  5137. \uccode`
  5138. \catcode`
  5139. =\active \def 
  5140. {\~{n}}
  5141. \catcode`
  5142. =\active \def 
  5143. {\~{N}}
  5144. \lccode`
  5145. \uccode`
  5146. \lccode`
  5147. \uccode`
  5148. \catcode`
  5149. =\active \def 
  5150. {\`{o}}
  5151. \catcode`
  5152. =\active \def 
  5153. {\`{O}}
  5154. \lccode`
  5155. \uccode`
  5156. \lccode`
  5157. \uccode`
  5158. \catcode`
  5159. =\active \def 
  5160. {\'{o}}
  5161. \catcode`
  5162. =\active \def 
  5163. {\'{O}}
  5164. \lccode`
  5165. \uccode`
  5166. \lccode`
  5167. \uccode`
  5168. \catcode`
  5169. =\active \def 
  5170. {\^{o}}
  5171. \catcode`
  5172. =\active \def 
  5173. {\^{O}}
  5174. \lccode`
  5175. \uccode`
  5176. \lccode`
  5177. \uccode`
  5178. \catcode`
  5179. =\active \def 
  5180. {\~{o}}
  5181. \catcode`
  5182. =\active \def 
  5183. {\~{O}}
  5184. \lccode`
  5185. \uccode`
  5186. \lccode`
  5187. \uccode`
  5188. \catcode`
  5189. =\active \def 
  5190. {\"{o}}
  5191. \catcode`
  5192. =\active \def 
  5193. {\"{O}}
  5194. \lccode`
  5195. \uccode`
  5196. \lccode`
  5197. \uccode`
  5198. \catcode`
  5199. =\active \def 
  5200. \catcode`
  5201. =\active \def 
  5202. \lccode`
  5203. \uccode`
  5204. \catcode`
  5205. =\active \def 
  5206. {$\times$}
  5207. \lccode`
  5208. \uccode`
  5209. \catcode`
  5210. =\active \def 
  5211. {$\div$}
  5212. \lccode`
  5213. \uccode`
  5214. \lccode`
  5215. \uccode`
  5216. \catcode`
  5217. =\active \def 
  5218. {\`{u}}
  5219. \catcode`
  5220. =\active \def 
  5221. {\`{U}}
  5222. \lccode`
  5223. \uccode`
  5224. \lccode`
  5225. \uccode`
  5226. \catcode`
  5227. =\active \def 
  5228. {\'{u}}
  5229. \catcode`
  5230. =\active \def 
  5231. {\'{U}}
  5232. \lccode`
  5233. \uccode`
  5234. \lccode`
  5235. \uccode`
  5236. \catcode`
  5237. =\active \def 
  5238. {\^{u}}
  5239. \catcode`
  5240. =\active \def 
  5241. {\^{U}}
  5242. \lccode`
  5243. \uccode`
  5244. \lccode`
  5245. \uccode`
  5246. \catcode`
  5247. =\active \def 
  5248. {\"{u}}
  5249. \catcode`
  5250. =\active \def 
  5251. {\"{U}}
  5252. \lccode`
  5253. \uccode`
  5254. \lccode`
  5255. \uccode`
  5256. \catcode`
  5257. =\active \def 
  5258. {\'{y}}
  5259. \catcode`
  5260. =\active \def 
  5261. {\'{Y}}
  5262. \lccode`
  5263. \uccode`
  5264. \catcode`
  5265. =\active \def 
  5266. {\ss}
  5267. \lccode`
  5268. \uccode`
  5269. \catcode`
  5270. =\active \def 
  5271. {\"{y}}
  5272. \lccode`
  5273. \uccode`
  5274. \catcode`
  5275. =\active \def 
  5276. \lccode`
  5277. \uccode`
  5278. \catcode`
  5279. =\active \def 
  5280. {\pounds}
  5281. \lccode`
  5282. \uccode`
  5283. \catcode`
  5284. =\active \def 
  5285. \lccode`
  5286. \uccode`
  5287. \catcode`
  5288. =\active \def 
  5289. {\copyright}
  5290. \lccode`
  5291. \uccode`
  5292. \catcode`
  5293. =\active \def 
  5294. {\leavevmode\kern-.1em\raise.5ex\hbox{\b{a}}}
  5295. \lccode`
  5296. \uccode`
  5297. \catcode`
  5298. =\active \def 
  5299. {$\ll$}
  5300. \lccode`
  5301. \uccode`
  5302. \catcode`
  5303. =\active \def 
  5304. {$\neg$}
  5305. \lccode`
  5306. \uccode`
  5307. \catcode`
  5308. =\active \def 
  5309. {$\pm$}
  5310. \lccode`
  5311. \uccode`
  5312. \catcode`
  5313. =\active \def 
  5314. {\leavevmode\kern.1em\raise.5ex\hbox{\the\scriptfont0 2}}
  5315. \lccode`
  5316. \uccode`
  5317. \catcode`
  5318. =\active \def 
  5319. {\leavevmode\kern.1em\raise.5ex\hbox{\the\scriptfont0 3}}
  5320. \lccode`
  5321. \uccode`
  5322. \catcode`
  5323. =\active \def 
  5324. {$\mu$}
  5325. \lccode`
  5326. \uccode`
  5327. \catcode`
  5328. =\active \def 
  5329. \lccode`
  5330. \uccode`
  5331. \catcode`
  5332. =\active \def 
  5333. {\leavevmode\kern.1em\raise.5ex\hbox{\the\scriptfont0 1}}
  5334. \lccode`
  5335. \uccode`
  5336. \catcode`
  5337. =\active \def 
  5338. {\leavevmode\kern-.1em\raise.5ex\hbox{\b{o}}}
  5339. \lccode`
  5340. \uccode`
  5341. \catcode`
  5342. =\active \def 
  5343. {$\gg$}
  5344. \lccode`
  5345. \uccode`
  5346. \catcode`
  5347. =\active \def 
  5348. {\leavevmode\kern.1em\raise.5ex\hbox{\the\scriptfont0 1}\kern-.1em/\kern-.15em\lower.25ex\hbox{\the\scriptfont0 4}}
  5349. \lccode`
  5350. \uccode`
  5351. \catcode`
  5352. =\active \def 
  5353. {\leavevmode\kern.1em\raise.5ex\hbox{\the\scriptfont0 1}\kern-.1em/\kern-.15em\lower.25ex\hbox{\the\scriptfont0 2}}
  5354. \lccode`
  5355. \uccode`
  5356. \catcode`
  5357. =\active \def 
  5358. {\leavevmode\kern.1em\raise.5ex\hbox{\the\scriptfont0 3}\kern-.1em/\kern-.15em\lower.25ex\hbox{\the\scriptfont0 4}}
  5359. \lccode`
  5360. \uccode`
  5361. \catcode`
  5362. =\active \def 
  5363. % After transferring files there's sometimes an Ctrl-Z at the end.
  5364. % (This could also handled in the CodePage with a line ^^Z>^^@)
  5365. \catcode`^^Z=9                          % ignore it or ...
  5366. %\catcode`^^Z=\active \def^^Z{\endinput}% ... make it active
  5367. \fi\fi
  5368. \endinput
  5369.